fix(bundler): reject non-mapping 'integration' in a bundle manifest (#3629)

BundleManifest.from_dict guarded 'requires' and 'provides' with
"must be a mapping when present", but a present-but-non-mapping 'integration'
(e.g. a bare string "copilot") silently failed the isinstance(dict) check and
was dropped — leaving the bundle wrongly integration-agnostic (is_agnostic()
True) instead of surfacing the authoring mistake. Add the same guard so
'integration' is consistent with its sibling mapping fields.

Test: integration='copilot' now raises BundlerError (fails before: silently
dropped, no raise).

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ali jawwad
2026-07-22 17:38:36 +05:00
committed by GitHub
parent aee9df00d4
commit cbfb9f01f7
2 changed files with 15 additions and 0 deletions

View File

@@ -122,6 +122,11 @@ class BundleManifest:
integration = None
integration_raw = data.get("integration")
# Mirror the requires/provides guards above: a present-but-non-mapping
# 'integration' (e.g. a bare string "copilot") was silently dropped,
# leaving the bundle wrongly integration-agnostic. Reject it instead.
if integration_raw is not None and not isinstance(integration_raw, dict):
raise BundlerError("'integration' must be a mapping when present.")
if isinstance(integration_raw, dict) and integration_raw.get("id"):
integration = IntegrationRef(id=str(integration_raw["id"]).strip())

View File

@@ -124,3 +124,13 @@ def test_string_mcp_rejected_not_split_per_character():
data["requires"]["mcp"] = "github"
with pytest.raises(BundlerError, match="'requires.mcp' must be a list of strings"):
BundleManifest.from_dict(data)
def test_string_integration_rejected_not_silently_dropped():
# A present-but-non-mapping 'integration' (a bare string) was silently
# dropped, leaving the bundle wrongly integration-agnostic. Reject it like
# the sibling requires/provides mapping fields.
data = valid_manifest_dict()
data["integration"] = "copilot"
with pytest.raises(BundlerError, match="'integration' must be a mapping when present"):
BundleManifest.from_dict(data)