{"record":{"id":"d89d252010e4be55","repo":"Hmbown/CodeWhale","slug":"fragmentid-missing-required-variant-name","errorCode":null,"errorMessage":"FragmentId missing required variant {name}","messagePattern":"FragmentId missing required variant (.+?)","errorType":"exception","errorClass":"RuntimeContractError","httpStatus":null,"severity":"error","filePath":"scripts/check-runtime-contract-budget.py","lineNumber":532,"sourceCode":"        )\n\n    # Ensure every injection type is in FragmentId::all() and the\n    # project-instruction import is present as a typed fragment.\n    required_fragments = [\n        \"Workspace\",\n        \"Permissions\",\n        \"Route\",\n        \"AgentTopology\",\n        \"SkillsTools\",\n        \"TokenBudget\",\n        \"ProjectInstructions\",\n        \"Constitution\",\n    ]\n    for name in required_fragments:\n        if f\"Self::{name}\" not in text and f\"{name} =>\" not in text and f'\"{name.lower()}\"' not in text.lower():\n            # Fallback: search for enum variant declaration\n            if not re.search(rf\"\\b{name}\\b\", text):\n                raise RuntimeContractError(\n                    f\"FragmentId missing required variant {name}\"\n                )\n    # Marker stability — these strings are pinned by tests / prefix cache\n    required_markers = [\n        \"<!-- cw:ctx:workspace -->\",\n        \"<!-- cw:ctx:project_instructions -->\",\n        \"<!-- cw:ctx:constitution -->\",\n    ]\n    for marker in required_markers:\n        if marker not in text:\n            raise RuntimeContractError(\n                f\"bounded fragment module missing required marker {marker!r}\"\n            )\n\n    # Project-instruction import must be a typed fragment, not ad-hoc\n    if \"load_project_instruction_fragment\" not in text:\n        raise RuntimeContractError(\n            \"bounded fragment module must expose load_project_instruction_fragment (project-instruction import as typed fragment)\"","sourceCodeStart":514,"sourceCodeEnd":550,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/scripts/check-runtime-contract-budget.py#L514-L550","documentation":"The gate verifies the FragmentId enum in crates/core/src/fragments.rs keeps all eight injection-type variants (Workspace, Permissions, Route, AgentTopology, SkillsTools, TokenBudget, ProjectInstructions, Constitution). It probes for 'Self::Name', 'Name =>', or the lowercased name, then falls back to a word-boundary regex over the whole file - so it only fires when the variant name appears nowhere at all, i.e. it was renamed or removed.","triggerScenarios":"Renaming a variant everywhere in fragments.rs (Constitution -> Charter); deleting a variant when merging injection types; moving FragmentId out of fragments.rs so the names no longer occur in the file the gate reads.","commonSituations":"Terminology refactors ('Constitution' -> 'Principles'); collapsing Workspace+Route into one fragment; extracting FragmentId into a submodule during a model_context reorganization.","solutions":["Restore the missing variant (named in the error) in the FragmentId enum in crates/core/src/fragments.rs","If a rename is intentional, either keep the required enum name and map display labels separately, or update required_fragments in scripts/check-runtime-contract-budget.py:518-527 in the same reviewed commit","Confirm absence first: 'grep -n Constitution crates/core/src/fragments.rs'"],"exampleFix":"// before (crates/core/src/fragments.rs)\npub enum FragmentId {\n    Workspace,\n    Permissions,\n    // Constitution removed during merge with Workspace\n}\n\n// after\npub enum FragmentId {\n    Workspace,\n    Permissions,\n    Constitution,\n}","handlingStrategy":"try-catch","validationCode":"from pathlib import Path\ntext = Path(\"crates/core/src/fragments.rs\").read_text(encoding=\"utf-8\")\nrequired = [\"Workspace\", \"Permissions\", \"Route\", \"AgentTopology\", \"SkillsTools\", \"TokenBudget\", \"ProjectInstructions\", \"Constitution\"]\nmissing = [name for name in required if name not in text]\nassert not missing, f\"FragmentId variants missing: {missing}\"","typeGuard":"def is_runtime_contract_error(exc: BaseException) -> bool:\n    return isinstance(exc, ValueError) and type(exc).__name__ == \"RuntimeContractError\"","tryCatchPattern":"try:\n    check_fragment_caps()\nexcept RuntimeContractError as error:\n    print(f\"[gate] {error}\", file=sys.stderr)\n    raise SystemExit(2)","preventionTips":["When renaming a FragmentId variant, update required_fragments in the checker in the same commit","Keep display/label mapping separate from enum variant names so renames are rarely needed","CI: run the checker on every PR touching crates/core/src/fragments.rs"],"tags":["python","ci","static-analysis","rust","enum"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}