Hmbown/CodeWhale · error · RuntimeContractError
missing TUI fragment module: {tui_fragment} ({error})
Error message
missing TUI fragment module: {tui_fragment} ({error}) What it means
After gating crates/core/src/fragments.rs, the checker reads the TUI-side module crates/tui/src/model_context/fragment.rs; a FileNotFoundError raises this (the raw OS error is embedded in the message). It means the unified TUI fragment module was deleted, moved, or renamed while the contract still requires the TUI and core to share one fragment boundary.
Source
Thrown at scripts/check-runtime-contract-budget.py:591
"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"
)
# TUI must be unified with the core boundary (shared crates/core module)
tui_fragment = REPO_ROOT / "crates" / "tui" / "src" / "model_context" / "fragment.rs"
try:
tui_text = tui_fragment.read_text(encoding="utf-8")
except FileNotFoundError as error:
raise RuntimeContractError(
f"missing TUI fragment module: {tui_fragment} ({error})"
) from error
if "codewhale_core::fragments" not in tui_text:
raise RuntimeContractError(
"TUI model_context/fragment.rs must re-export caps from codewhale_core::fragments (shared crates/core boundary)"
)
if "ProjectInstructions" not in tui_text:
raise RuntimeContractError(
"TUI fragment module must include ProjectInstructions variant (unified with core)"
)
if "MAX_FRAGMENT_BYTES" not in tui_text:
raise RuntimeContractError(
"TUI fragment module must enforce MAX_FRAGMENT_BYTES (10K-token ceiling)"
)
if "matches_text" not in tui_text:
raise RuntimeContractError(
"TUI fragment module must expose a matches_text recognizer"
)View on GitHub (pinned to 8880682c63)
Solutions
- Restore the file: 'git checkout HEAD -- crates/tui/src/model_context/fragment.rs' if the move was accidental
- If the move is intentional, update tui_fragment in scripts/check-runtime-contract-budget.py:587 to the new path in the same commit
- Confirm exact path/casing: 'ls crates/tui/src/model_context/'
Example fix
# before (scripts/check-runtime-contract-budget.py) tui_fragment = REPO_ROOT / "crates" / "tui" / "src" / "context" / "fragment.rs" # after (matches the moved file) tui_fragment = REPO_ROOT / "crates" / "tui" / "src" / "model_context" / "fragment.rs"
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
p = Path("crates/tui/src/model_context/fragment.rs")
assert p.is_file(), f"TUI fragment module missing at {p}" Type guard
def is_runtime_contract_error(exc: BaseException) -> bool:
return isinstance(exc, ValueError) and type(exc).__name__ == "RuntimeContractError" Try / catch
try:
check_fragment_caps()
except RuntimeContractError as error:
print(f"[gate] {error}", file=sys.stderr)
raise SystemExit(2) Prevention
- Before moving crates/tui/src/model_context/fragment.rs, update tui_fragment in the checker in the same commit
- CI: assert both fragment module paths exist before running the gate
- Treat the core and TUI fragment files as a pair - any path change touches both sides
When it happens
Trigger: Moving or deleting crates/tui/src/model_context/fragment.rs during a tui reorganization; an incomplete unification that removed the TUI file; renaming fragment.rs to fragments.rs (path is case-sensitive).
Common situations: Crates reshuffles; merging a branch that relocated model_context; accidental deletions in dirty worktrees.
Related errors
- TUI model_context/fragment.rs must re-export caps from codew
- TUI fragment module must include ProjectInstructions variant
- missing {kind}: {path}
- missing bounded fragment module: {FRAGMENT_MODULE} ({error})
- DEFAULT_FRAGMENT_MAX_BYTES ({default_bytes}) must not exceed
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/84d429086cff7df1.
Report an issue: GitHub.