{"record":{"id":"260918dc22dcacf5","repo":"calesthio/OpenMontage","slug":"pipeline-manifest-get-name-unknown-r-does","errorCode":null,"errorMessage":"Pipeline {manifest.get('name', 'unknown')!r} does not permit {extension_type}. Set extensions.{extension_type}: true in the pipeline manifest to allow this.","messagePattern":"Pipeline (.+?) does not permit (.+?)\\. Set extensions\\.(.+?): true in the pipeline manifest to allow this\\.","errorType":"validation","errorClass":"ExtensionNotPermitted","httpStatus":null,"severity":"error","filePath":"lib/pipeline_loader.py","lineNumber":224,"sourceCode":"\n    Args:\n        manifest: Loaded pipeline manifest dict.\n        extension_type: One of 'custom_scripts', 'custom_playbooks',\n                        'custom_skills', 'custom_tools'.\n\n    Raises:\n        ExtensionNotPermitted: If the extension is not allowed.\n    \"\"\"\n    valid_extensions = {\"custom_scripts\", \"custom_playbooks\", \"custom_skills\", \"custom_tools\"}\n    if extension_type not in valid_extensions:\n        raise ValueError(\n            f\"Unknown extension type {extension_type!r}. \"\n            f\"Valid types: {sorted(valid_extensions)}\"\n        )\n\n    extensions = manifest.get(\"extensions\", {})\n    if not extensions.get(extension_type, False):\n        raise ExtensionNotPermitted(\n            f\"Pipeline {manifest.get('name', 'unknown')!r} does not permit \"\n            f\"{extension_type}. Set extensions.{extension_type}: true in the \"\n            f\"pipeline manifest to allow this.\"\n        )\n\n\ndef get_permitted_extensions(manifest: dict) -> dict[str, bool]:\n    \"\"\"Return the extension permission flags for a pipeline.\"\"\"\n    defaults = {\n        \"custom_scripts\": False,\n        \"custom_playbooks\": False,\n        \"custom_skills\": False,\n        \"custom_tools\": False,\n    }\n    extensions = manifest.get(\"extensions\", {})\n    return {k: extensions.get(k, v) for k, v in defaults.items()}\n","sourceCodeStart":206,"sourceCodeEnd":241,"githubUrl":"https://github.com/calesthio/OpenMontage/blob/95e1c3d0ab93482159818560f6a8c8e866b9139f/lib/pipeline_loader.py#L206-L241","documentation":"Raised as ExtensionNotPermitted by lib/pipeline_loader.py when a capability extension type is valid but the pipeline manifest does not opt in — extensions.<type> is absent or false in the manifest YAML. Pipelines run least-privilege by default: custom scripts, playbooks, skills, and tools are disabled unless the manifest explicitly sets the corresponding flag to true. This prevents an agent from injecting arbitrary executable capabilities into a pipeline that was not designed to allow them.","triggerScenarios":"Calling the extension enforcement with extension_type='custom_scripts' on a manifest whose extensions block is missing or has custom_scripts: false; loading a manifest written before the extensions feature existed (all flags default false).","commonSituations":"Trying to attach a custom tool or script to a stock pipeline that never enabled extensions; a newly copied manifest that dropped the extensions block; expecting extensions to be enabled by default.","solutions":["Edit the pipeline manifest YAML and add extensions.<extension_type>: true under the extensions block.","If you don't control the manifest, switch to a pipeline that permits the extension or ask the manifest owner to opt in.","Verify the permission programmatically with get_permitted_extensions(manifest) before attempting to register the extension."],"exampleFix":"# pipeline.yaml — before\nname: my_pipeline\nstages: [...]\n\n# pipeline.yaml — after\nname: my_pipeline\nextensions:\n  custom_scripts: true\nstages: [...]","handlingStrategy":"validation","validationCode":"from lib.pipeline_loader import get_permitted_extensions\n\nperms = get_permitted_extensions(manifest)\nif not perms.get(extension_type, False):\n    raise SystemExit(\n        f\"Pipeline {manifest.get('name')!r} does not permit {extension_type}. \"\n        \"Enable extensions.\" + extension_type + \": true in the manifest.\"\n    )","typeGuard":"from lib.pipeline_loader import get_permitted_extensions\n\ndef extension_permitted(manifest: dict, extension_type: str) -> bool:\n    return get_permitted_extensions(manifest).get(extension_type, False)","tryCatchPattern":"from lib.pipeline_loader import ExtensionNotPermitted\n\ntry:\n    enforce_extension_allowed(manifest, extension_type)\nexcept ExtensionNotPermitted as e:\n    raise SystemExit(f\"Not allowed by this pipeline: {e}\") from e","preventionTips":["Check get_permitted_extensions(manifest) before registering any custom capability.","Keep the extensions opt-in flags visible in manifest reviews — they widen what an agent may execute.","Default-deny is intentional; don't blanket-enable all four flags without a reason."],"tags":["pipeline","extensions","permissions","security"],"backgroundTag":null,"analyzedSha":"95e1c3d0ab93482159818560f6a8c8e866b9139f","analyzedAt":"2026-08-15T06:31:20.014Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}