Hmbown/CodeWhale · error · RuntimeContractError
tool surface_profile must be ` `, got
Error message
{kind} tool surface_profile must be `{TOOL_SURFACE_PROFILE}`, got {profile!r} What it means
validate_identity_structure pins the tool catalog to the script's canonical surface profile constant TOOL_SURFACE_PROFILE. If the document's tool_catalog.surface_profile differs, the contract identity is not comparable with the current script version, so it throws. This prevents mixing receipts from different catalog shapes.
Solutions
- Regenerate the receipt with the current script so surface_profile matches TOOL_SURFACE_PROFILE
- Read TOOL_SURFACE_PROFILE in check-runtime-contract-budget.py and correct the JSON value to that exact string
- If the profile change is intentional, update TOOL_SURFACE_PROFILE and regenerate all receipts consistently
Example fix
// before
{"tool_catalog": {"surface_profile": "codewhale-v1"}}
// after (value = TOOL_SURFACE_PROFILE in the script)
{"tool_catalog": {"surface_profile": "codewhale-v2"}} Defensive patterns
Strategy: validation
Validate before calling
from scripts.check_runtime_contract_budget import TOOL_SURFACE_PROFILE
assert doc.get("tool_catalog", {}).get("surface_profile") == TOOL_SURFACE_PROFILE, \
f"expected surface_profile {TOOL_SURFACE_PROFILE!r}" Try / catch
try:
validate_receipt(receipt)
except RuntimeContractError as e:
if "surface_profile must be" in str(e):
receipt = regenerate_receipt() # version skew: rebuild with current script
else:
raise Prevention
- Never hardcode the profile string; import TOOL_SURFACE_PROFILE
- Regenerate all receipts whenever the surface profile constant changes
- Store the script version in receipts to detect version skew early
When it happens
Trigger: validate_receipt or validate_budget finds tool_catalog.surface_profile set to any value other than TOOL_SURFACE_PROFILE (or missing, which surfaces as error 800 first).
Common situations: Receipt generated by an older/newer script version where the profile string was bumped; manually crafted JSON with a guessed profile value; a document from another repo/copy with a divergent constant.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Codewhale metadata event was not a terminal receipt
- field ` ` must be sorted unique non-empty strings
- field ` ` must match the owned sorted tool_names
- is missing required field
- metric ` ` must equal the owned tool_names length ( )
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/ee4f160edbc2c961.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/check-runtime-contract-budget.py:208
def required_value(document: dict[str, Any], path: MetricPath, kind: str) -> Any:
value: Any = document
dotted = ".".join(path)
for part in path:
if not isinstance(value, dict) or part not in value:
raise RuntimeContractError(f"{kind} is missing required field `{dotted}`")
value = value[part]
return value
def tool_identity_digest(names: list[str]) -> str:
return hashlib.sha256("\0".join(names).encode("utf-8")).hexdigest()
def validate_identity_structure(document: dict[str, Any], kind: str) -> None:
profile = required_value(document, ("tool_catalog", "surface_profile"), kind)
if profile != TOOL_SURFACE_PROFILE:
raise RuntimeContractError(
f"{kind} tool surface_profile must be `{TOOL_SURFACE_PROFILE}`, "
f"got {profile!r}"
)
shell = required_value(document, ("tool_catalog", "execution_shell"), kind)
if shell != "bash":
raise RuntimeContractError(
f"{kind} tool execution_shell must be `bash`, got {shell!r}"
)
for mode, _label in VISIBLE_MODES:
for surface, _surface_label in TOOL_SURFACES:
base = ("tool_catalog", "modes", mode, surface)
names = required_value(document, (*base, "tool_names"), kind)
dotted_names = ".".join((*base, "tool_names"))
if (
not isinstance(names, list)
or any(not isinstance(name, str) or not name for name in names)View on GitHub (pinned to 433685b202)