{"record":{"id":"db74c271b7fc4d88","repo":"shareAI-lab/learn-claude-code","slug":"workflow-meta-name-denied-by-settings","errorCode":null,"errorMessage":"workflow '{meta['name']}' denied by settings","messagePattern":"workflow '(.+?)' denied by settings","errorType":"validation","errorClass":"WorkflowInputError","httpStatus":null,"severity":"error","filePath":"s16_workflow_runtime/code.py","lineNumber":144,"sourceCode":"    if not isinstance(meta[\"name\"], str) or not WORKFLOW_NAME_RE.fullmatch(meta[\"name\"]):\n        raise WorkflowInputError(\n            \"meta.name must be a 1-64 character slug using letters, numbers, '.', '_', or '-'\"\n        )\n    if not isinstance(meta[\"description\"], str):\n        raise WorkflowInputError(\"meta.description must be a string\")\n    if \"phases\" in meta:\n        if not isinstance(meta[\"phases\"], list) or not all(\n            isinstance(phase, str) and phase for phase in meta[\"phases\"]\n        ):\n            raise WorkflowInputError(\"meta.phases must be a list of non-empty strings\")\n    return meta\n\n\ndef check_permission(meta, settings=None):\n    \"\"\"Apply the s03 allow/deny gate before launching a workflow.\"\"\"\n    settings = settings or {}\n    if meta[\"name\"] in settings.get(\"deny\", []):\n        raise WorkflowInputError(f\"workflow '{meta['name']}' denied by settings\")\n    return \"allow\"\n\n\n# -- Minimal JSON Schema --\nclass SimpleJsonSchema:\n    \"\"\"Tiny validator backing agent({schema}):\n    object/array/string/boolean/number + required keys.\"\"\"\n\n    def __init__(self, schema):\n        self.schema = schema\n\n    def validate(self, value, schema=None):\n        schema = self.schema if schema is None else schema\n        if \"enum\" in schema and value not in schema[\"enum\"]:\n            return False, f\"expected one of {schema['enum']}\"\n        t = schema.get(\"type\")\n        if t == \"object\":\n            if not isinstance(value, dict):","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/shareAI-lab/learn-claude-code/blob/985456f4adea6f4df8fbad4112245dbd97444eae/s16_workflow_runtime/code.py#L126-L162","documentation":"check_permission applies the s03 allow/deny gate before launch: if meta['name'] appears in settings['deny'], the workflow is refused with WorkflowInputError naming the denied workflow. This is a policy enforcement error, not a data-format one — the meta is valid but the operator has banned this workflow by name.","triggerScenarios":"settings = {\"deny\": [\"ingest\"]} and run(meta={\"name\": \"ingest\", ...}). Deny lists copied from another environment where the same name means a different workflow. Names added to deny for incident response while scheduled jobs keep firing.","commonSituations":"Operators disabling a misbehaving workflow via settings, then a cron/scheduler still attempting it. Config promotion carrying a production deny list into staging where the name collides with a legitimate workflow.","solutions":["If the workflow should run, remove or correct its name in the settings deny list","If denial is intended, stop the invoking scheduler/job as well","Pre-check before launch: if meta['name'] in settings.get('deny', []), skip gracefully instead of letting the exception propagate"],"exampleFix":"# before\nsettings = {\"deny\": [\"ingest\"]}\nrun(workflow, meta=meta, settings=settings)  # raises if name == 'ingest'\n\n# after\nif meta[\"name\"] not in settings.get(\"deny\", []):\n    run(workflow, meta=meta, settings=settings)","handlingStrategy":"validation","validationCode":"def workflow_is_allowed(meta: dict, settings: dict) -> bool:\n    return meta.get(\"name\") not in (settings or {}).get(\"deny\", [])\n\nassert workflow_is_allowed(meta, settings), f\"{meta['name']!r} is denied by settings\"","typeGuard":"def is_not_denied(meta: dict, settings: dict | None) -> bool:\n    return meta.get(\"name\") not in (settings or {}).get(\"deny\", [])","tryCatchPattern":"try:\n    check_permission(meta, settings)\nexcept WorkflowInputError as exc:\n    if \"denied by settings\" in str(exc):\n        # intentional policy: skip gracefully instead of crashing the scheduler\n        log.info(\"skipping denied workflow %s\", meta[\"name\"])\n        return\n    raise","preventionTips":["Pre-check names against the deny list before launching","Keep deny lists per environment and review them during promotion","When disabling a workflow, also disable its scheduler entry"],"tags":["workflow","permissions","policy","configuration"],"backgroundTag":null,"analyzedSha":"985456f4adea6f4df8fbad4112245dbd97444eae","analyzedAt":"2026-08-14T22:02:26.028Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}