{"record":{"id":"7e0e04f3ed508dfa","repo":"github/spec-kit","slug":"failed-to-parse-extension-registry-registry-ex","errorCode":null,"errorMessage":"Failed to parse extension registry {registry}: {exc}","messagePattern":"Failed to parse extension registry (.+?): (.+?)","errorType":"exception","errorClass":"TemplateResolutionError","httpStatus":null,"severity":"error","filePath":"scripts/python/common.py","lineNumber":254,"sourceCode":"            if p.is_dir() and _is_safe_component(p.name)\n        )\n    except OSError:\n        return []\n\n\ndef _sorted_extension_ids(extensions_dir: Path) -> list[str]:\n    registry = extensions_dir / \".registry\"\n    registered_ids: set[str] = set()\n    extensions: dict[object, object] = {}\n    if os.path.lexists(registry):\n        if not registry.is_file():\n            raise TemplateResolutionError(\n                f\"Invalid extension registry {registry}: not a regular file\"\n            )\n        try:\n            data = json.loads(registry.read_text(encoding=\"utf-8\"))\n        except (OSError, UnicodeError, json.JSONDecodeError) as exc:\n            raise TemplateResolutionError(\n                f\"Failed to parse extension registry {registry}: {exc}\"\n            ) from exc\n        if not isinstance(data, dict):\n            raise TemplateResolutionError(\n                f\"Invalid extension registry {registry}: root must be a mapping\"\n            )\n        raw_extensions = data.get(\"extensions\", {})\n        if not isinstance(raw_extensions, dict):\n            raise TemplateResolutionError(\n                f\"Invalid extension registry {registry}: \"\n                \"'extensions' must be a mapping\"\n            )\n        extensions = raw_extensions\n        registered_ids = {\n            ext_id for ext_id in extensions if isinstance(ext_id, str)\n        }\n\n    ranked: list[tuple[int, str]] = []","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/github/spec-kit/blob/bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c/scripts/python/common.py#L236-L272","documentation":"_enforce_workflow_yaml_size() is the final in-memory gate: after a workflow YAML payload is fully read (download or local content), len(data) is compared against _MAX_WORKFLOW_YAML_BYTES (5 MiB) and ValueError is raised if exceeded. It catches anything the network checks missed — decoded decompressed bodies, locally supplied content, or data assembled by callers.","triggerScenarios":"Any code path that stages a workflow YAML whose bytes exceed 5 MiB: a downloaded body that was gzip/deflate encoded so its decoded size exceeded the wire checks, or a caller passing a large local workflow definition into the staging pipeline.","commonSituations":"Content-Encoding (gzip/brotli) responses whose decoded size exceeds 5 MiB while wire checks passed; workflows embedding huge inline data URIs or pasted blobs; generated workflows from templates with unbounded inline content.","solutions":["Shrink the workflow YAML: move large inline payloads (scripts, base64 blobs) to referenced files within the bundle","Regenerate the workflow without embedded assets and validate with `wc -c workflow.yaml`","If serving over HTTP, disable transfer compression for this asset so wire checks see the true size earlier with a clearer error","Split the workflow into multiple smaller workflows"],"exampleFix":"# before\n# workflow.yaml embeds a 6 MiB base64 dataset in `steps.data`\n\n# after\n# move the dataset to an adjacent file and reference it\nsteps:\n  - run: scripts/load_data.py  # reads data.bin next to workflow.yaml","handlingStrategy":"validation","validationCode":"MAX = 5 * 1024 * 1024\n\nif len(workflow_yaml_bytes) > MAX:\n    raise ValueError(f'workflow YAML is {len(workflow_yaml_bytes)} bytes; limit is {MAX}')\n# only then pass to the staging pipeline","typeGuard":null,"tryCatchPattern":"try:\n    stage_workflow(workflow_id, yaml_bytes)\nexcept ValueError as e:\n    if 'workflow size limit' in str(e):\n        raise SystemExit('workflow YAML too large; externalize inline blobs and retry') from e\n    raise","preventionTips":["Keep workflow YAML lean: reference sibling files instead of inlining base64/scripts","wc -c workflow.yaml before adding it to the project or CI","Watch for content-encoding: downloads may pass wire checks but fail the decoded-size gate"],"tags":["workflow","size-limit","yaml","validation"],"backgroundTag":null,"analyzedSha":"bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c","analyzedAt":"2026-08-14T19:43:37.150Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}