Hmbown/CodeWhale · error · RuntimeContractError

runtime-contract measurement failed with exit code {proc.ret

Error message

runtime-contract measurement failed with exit code {proc.returncode}

What it means

run_measurement() shells out to scripts/measure-runtime-contract.py (which itself runs `cargo test --locked -p codewhale-tui --lib core::engine::tests::<name> -- --ignored --exact --nocapture --test-threads=1`) with CARGO_NET_OFFLINE=true. A non-zero child exit code raises this error after echoing the child's stdout/stderr, so the underlying cargo failure is visible above the message. This is an environment/build failure, not a contract verdict.

Source

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

        temporary_path.unlink(missing_ok=True)
        raise


def run_measurement() -> dict[str, Any]:
    env = os.environ.copy()
    env["CARGO_NET_OFFLINE"] = "true"
    proc = subprocess.run(
        [sys.executable, str(MEASURE_SCRIPT)],
        cwd=REPO_ROOT,
        env=env,
        capture_output=True,
        text=True,
        check=False,
    )
    sys.stderr.write(proc.stderr)
    if proc.returncode != 0:
        sys.stdout.write(proc.stdout)
        raise RuntimeContractError(
            f"runtime-contract measurement failed with exit code {proc.returncode}"
        )
    try:
        receipt = json.loads(proc.stdout)
    except json.JSONDecodeError as error:
        raise RuntimeContractError(f"measurement emitted invalid JSON: {error}") from error
    if not isinstance(receipt, dict):
        raise RuntimeContractError("measurement top level must be an object")
    validate_receipt(receipt)
    return receipt


def update_command(receipt_path: Path | None, budget_path: Path) -> str:
    parts = ["python3", "scripts/check-runtime-contract-budget.py"]
    if receipt_path is not None:
        parts.extend(["--receipt", str(receipt_path)])
    if budget_path != BUDGET_PATH:
        parts.extend(["--budget", str(budget_path)])

View on GitHub (pinned to 8880682c63)

Solutions

  1. Run the child directly to see the real failure: python3 scripts/measure-runtime-contract.py
  2. Warm the offline cache: cargo fetch --locked (so CARGO_NET_OFFLINE=true can resolve), and install the toolchain from rust-toolchain.toml
  3. Fix any workspace compile error the child reports - the gate compiles codewhale-tui --lib
  4. In CI, run this gate after the normal build job so caches and toolchain are already in place
Defensive patterns

Strategy: try-catch

Validate before calling

import shutil, subprocess, sys
from pathlib import Path


def measurement_prerequisites_ok() -> bool:
    if not Path("scripts/measure-runtime-contract.py").is_file():
        return False
    if shutil.which("cargo") is None:
        return False
    proc = subprocess.run(
        ["cargo", "metadata", "--locked", "--offline", "--format-version", "1"],
        capture_output=True,
        text=True,
    )
    return proc.returncode == 0  # offline dependency set is resolvable

Try / catch

import importlib.util

spec = importlib.util.spec_from_file_location(
    "crcb", "scripts/check-runtime-contract-budget.py"
)
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)

try:
    receipt = mod.run_measurement()
except mod.RuntimeContractError:
    # the child's stderr (and stdout on failure) were already echoed -
    # read them; exit code 2 mirrors the CLI's ERROR path
    raise SystemExit(2)

Prevention

When it happens

Trigger: cargo missing or older than rust-toolchain.toml pins; offline builds where CARGO_NET_OFFLINE=true hits unfetched registry crates (no prior cargo fetch, stale Cargo.lock); compile errors anywhere in the codewhale-tui dependency graph; the ignored metric test no longer existing or panicking.

Common situations: First run on a fresh CI container or a clean Nix shell without a warmed cargo cache; after a Cargo.lock bump that pulled new crates never vendored/fetched; local runs on a machine without the pinned toolchain.

Related errors


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