Hmbown/CodeWhale · error · RuntimeContractError

PROJECT_INSTRUCTION_CANDIDATES missing required entry

Error message

PROJECT_INSTRUCTION_CANDIDATES missing required entry {candidate!r}

What it means

After requiring PROJECT_INSTRUCTION_CANDIDATES to exist, check_fragment_caps scans fragments.rs for each required candidate file from issue #3978: .cursorrules, .clinerules, .windsurf/rules, .gemini, and .github/copilot-instructions.md. If any one literal is absent from the module text it names the missing entry. This keeps the typed project-instruction fragment covering the full set of supported editor instruction files.

Solutions

  1. Add the missing candidate literal (named in the error, e.g. '.gemini') back to PROJECT_INSTRUCTION_CANDIDATES in crates/core/src/fragments.rs.
  2. If a candidate path legitimately changed, update both the list and this script's required_candidates in scripts/check-runtime-contract-budget.py together (documented change, not a silent edit).
  3. Keep the list as literal string entries — the checker matches text, so computed/glob-based lists will fail.

Example fix

// before
pub const PROJECT_INSTRUCTION_CANDIDATES: &[&str] = &[".cursorrules", ".clinerules"];

// after
pub const PROJECT_INSTRUCTION_CANDIDATES: &[&str] = &[
    ".cursorrules",
    ".clinerules",
    ".windsurf/rules",
    ".gemini",
    ".github/copilot-instructions.md",
];
Defensive patterns

Strategy: validation

Validate before calling

required = ['.cursorrules', '.clinerules', '.windsurf/rules', '.gemini', '.github/copilot-instructions.md']
text = open('crates/core/src/fragments.rs').read()
missing = [c for c in required if c not in text]
assert not missing, f'missing candidates: {missing}'

Type guard

def candidates_complete(module_text: str) -> bool:
    return all(c in module_text for c in ('.cursorrules', '.clinerules', '.windsurf/rules', '.gemini', '.github/copilot-instructions.md'))

Try / catch

try:
    check_fragment_caps()
except RuntimeContractError as e:
    m = re.search(r"missing required entry (.+)", str(e))
    if m:
        append_candidate_to_list(m.group(1).strip("'\""))

Prevention

When it happens

Trigger: Running the contract check when PROJECT_INSTRUCTION_CANDIDATES exists in crates/core/src/fragments.rs but omits one or more of the five required candidate strings (trimmed list, renamed path, e.g. '.windsurfrules' instead of '.windsurf/rules').

Common situations: A developer trims the list to candidates their team actually uses; a candidate file is renamed upstream (e.g. .windsurf/rules layout change) and the entry is edited to match; the list is rewritten as a dynamic glob, dropping literal strings.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15). Data as JSON: /api/errors/ed015c11819a38b2. Report an issue: GitHub.

Appendix: source

Thrown at scripts/check-runtime-contract-budget.py:573

    if "load_project_instruction_fragment" not in text:
        raise RuntimeContractError(
            "bounded fragment module must expose load_project_instruction_fragment (project-instruction import as typed fragment)"
        )
    if "PROJECT_INSTRUCTION_CANDIDATES" not in text:
        raise RuntimeContractError(
            "bounded fragment module must define PROJECT_INSTRUCTION_CANDIDATES"
        )
    # Required candidate files from #3978
    required_candidates = [
        ".cursorrules",
        ".clinerules",
        ".windsurf/rules",
        ".gemini",
        ".github/copilot-instructions.md",
    ]
    for candidate in required_candidates:
        if candidate not in text:
            raise RuntimeContractError(
                f"PROJECT_INSTRUCTION_CANDIDATES missing required entry {candidate!r}"
            )

    # matches_text recognizer must exist on the fragment trait
    if "fn matches_text" not in text:
        raise RuntimeContractError(
            "bounded fragment module must define a matches_text recognizer on the fragment trait"
        )
    if "trait ContextFragment" not in text:
        raise RuntimeContractError(
            "bounded fragment module must define trait ContextFragment with matches_text"
        )

    # No unbounded fragment — enforce that creation clamps to MAX_FRAGMENT_BYTES
    if "MAX_FRAGMENT_BYTES" not in text or "enforce_byte_cap" not in text:
        raise RuntimeContractError(
            "bounded fragment module must enforce byte caps via enforce_byte_cap and MAX_FRAGMENT_BYTES"
        )

View on GitHub (pinned to 433685b202)