calesthio/OpenMontage · error · ExtensionNotPermitted

Pipeline {manifest.get('name', 'unknown')!r} does not permit

Error message

Pipeline {manifest.get('name', 'unknown')!r} does not permit {extension_type}. Set extensions.{extension_type}: true in the pipeline manifest to allow this.

What it means

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.

Source

Thrown at lib/pipeline_loader.py:224

    Args:
        manifest: Loaded pipeline manifest dict.
        extension_type: One of 'custom_scripts', 'custom_playbooks',
                        'custom_skills', 'custom_tools'.

    Raises:
        ExtensionNotPermitted: If the extension is not allowed.
    """
    valid_extensions = {"custom_scripts", "custom_playbooks", "custom_skills", "custom_tools"}
    if extension_type not in valid_extensions:
        raise ValueError(
            f"Unknown extension type {extension_type!r}. "
            f"Valid types: {sorted(valid_extensions)}"
        )

    extensions = manifest.get("extensions", {})
    if not extensions.get(extension_type, False):
        raise ExtensionNotPermitted(
            f"Pipeline {manifest.get('name', 'unknown')!r} does not permit "
            f"{extension_type}. Set extensions.{extension_type}: true in the "
            f"pipeline manifest to allow this."
        )


def get_permitted_extensions(manifest: dict) -> dict[str, bool]:
    """Return the extension permission flags for a pipeline."""
    defaults = {
        "custom_scripts": False,
        "custom_playbooks": False,
        "custom_skills": False,
        "custom_tools": False,
    }
    extensions = manifest.get("extensions", {})
    return {k: extensions.get(k, v) for k, v in defaults.items()}

View on GitHub (pinned to 95e1c3d0ab)

Solutions

  1. Edit the pipeline manifest YAML and add extensions.<extension_type>: true under the extensions block.
  2. If you don't control the manifest, switch to a pipeline that permits the extension or ask the manifest owner to opt in.
  3. Verify the permission programmatically with get_permitted_extensions(manifest) before attempting to register the extension.

Example fix

# pipeline.yaml — before
name: my_pipeline
stages: [...]

# pipeline.yaml — after
name: my_pipeline
extensions:
  custom_scripts: true
stages: [...]
Defensive patterns

Strategy: validation

Validate before calling

from lib.pipeline_loader import get_permitted_extensions

perms = get_permitted_extensions(manifest)
if not perms.get(extension_type, False):
    raise SystemExit(
        f"Pipeline {manifest.get('name')!r} does not permit {extension_type}. "
        "Enable extensions." + extension_type + ": true in the manifest."
    )

Type guard

from lib.pipeline_loader import get_permitted_extensions

def extension_permitted(manifest: dict, extension_type: str) -> bool:
    return get_permitted_extensions(manifest).get(extension_type, False)

Try / catch

from lib.pipeline_loader import ExtensionNotPermitted

try:
    enforce_extension_allowed(manifest, extension_type)
except ExtensionNotPermitted as e:
    raise SystemExit(f"Not allowed by this pipeline: {e}") from e

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of calesthio/OpenMontage@95e1c3d0ab (2026-08-15). Data as JSON: /api/errors/260918dc22dcacf5. Report an issue: GitHub.