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
- Add the missing candidate literal (named in the error, e.g. '.gemini') back to PROJECT_INSTRUCTION_CANDIDATES in crates/core/src/fragments.rs.
- 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).
- 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
- Never trim PROJECT_INSTRUCTION_CANDIDATES without updating required_candidates in the checker in the same commit.
- Keep candidate entries as plain string literals — the checker is a text match, not an AST parse.
- Add a unit-style smoke run of the script after any edit to the candidates list.
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
- bounded fragment module must define a matches_text…
- bounded fragment module must define…
- bounded fragment module must define trait ContextFragment…
- bounded fragment module must enforce byte caps via…
- TUI fragment module must include ProjectInstructions…
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)