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

  1. Restore the file: 'git checkout HEAD -- crates/tui/src/model_context/fragment.rs' if the move was accidental
  2. If the move is intentional, update tui_fragment in scripts/check-runtime-contract-budget.py:587 to the new path in the same commit
  3. 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

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


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/84d429086cff7df1. Report an issue: GitHub.