ruvnet/RuView · error · ValueError
Calibration bundle {path} missing key {key!r}
Error message
Calibration bundle {path} missing key {key!r} What it means
load_bundle() in scripts/calibration_lib.py reads a camera-room calibration bundle (the JSON that scripts/calibrate-camera-room.py writes via save_bundle) and validates that it contains the three keys the ADR-152 pipeline requires: camera_intrinsics, camera_to_room_extrinsics, and transceiver_geometry. It raises ValueError on the first key that is absent. The bundle couples camera intrinsics/extrinsics with WiFi transceiver geometry so every training label can be stamped with the deployment layout.
Source
Thrown at scripts/calibration_lib.py:334
"""
canonical = json.dumps(bundle, sort_keys=True, separators=(",", ":"))
return "sha256:" + hashlib.sha256(canonical.encode("utf-8")).hexdigest()
def save_bundle(bundle: dict, path: Path) -> None:
path = Path(path)
path.parent.mkdir(parents=True, exist_ok=True)
with open(path, "w", encoding="utf-8") as f:
json.dump(bundle, f, indent=2)
f.write("\n")
def load_bundle(path: Path) -> dict:
with open(path, "r", encoding="utf-8") as f:
bundle = json.load(f)
for key in ("camera_intrinsics", "camera_to_room_extrinsics", "transceiver_geometry"):
if key not in bundle:
raise ValueError(f"Calibration bundle {path} missing key {key!r}")
return bundle
# ---------------------------------------------------------------------------
# Keypoint transform (image -> room-frame bearing rays)
# ---------------------------------------------------------------------------
class CalibrationContext:
"""Pre-computed transform state for a collection session.
Scales the bundle's intrinsics to the live capture resolution (MediaPipe
keypoints are normalized [0,1], so we need the actual frame size to get
back to pixels before undistorting).
"""
def __init__(self, bundle: dict, frame_w: int, frame_h: int):
self.bundle = bundle
self.calibration_id = calibration_id(bundle)View on GitHub (pinned to 4685618388)
Solutions
- Regenerate the bundle with scripts/calibrate-camera-room.py, which writes all three keys via cal.save_bundle()
- Inspect what you actually have: python -c "import json; print(sorted(json.load(open('bundle.json'))))" and compare against the three exact snake_case key names
- If hand-authoring is unavoidable, include camera_intrinsics, camera_to_room_extrinsics, and transceiver_geometry exactly as spelled in the loop
- Verify you passed the intended path — an unrelated or partial JSON file is the usual culprit
Example fix
# before
calib = cal.load_bundle(Path("my_intrinsics.json")) # ValueError: missing 'transceiver_geometry'
# after
import json, pathlib
p = pathlib.Path("my_intrinsics.json")
keys = set(json.loads(p.read_text()))
missing = {"camera_intrinsics", "camera_to_room_extrinsics", "transceiver_geometry"} - keys
if missing:
raise SystemExit(f"{p} missing {sorted(missing)}; regenerate with scripts/calibrate-camera-room.py")
calib = cal.load_bundle(p) Defensive patterns
Strategy: validation
Validate before calling
import json
from pathlib import Path
REQUIRED_BUNDLE_KEYS = {"camera_intrinsics", "camera_to_room_extrinsics", "transceiver_geometry"}
def bundle_is_complete(path: Path) -> bool:
try:
keys = set(json.loads(Path(path).read_text(encoding="utf-8")))
except (OSError, json.JSONDecodeError):
return False
return REQUIRED_BUNDLE_KEYS <= keys
# before load_bundle:
# assert bundle_is_complete(my_bundle) or regenerate Try / catch
try:
bundle = cal.load_bundle(path)
except ValueError as e:
raise SystemExit(f"bad calibration bundle {path}: {e}; regenerate with scripts/calibrate-camera-room.py") from e Prevention
- Always produce bundles with scripts/calibrate-camera-room.py (save_bundle) instead of hand-writing JSON
- Keep bundles with the collection data they belong to, since labels are stamped with the calibration
- Add the three-key check to collection-script startup so a bad bundle fails before any capture session
When it happens
Trigger: Calling load_bundle(path) — e.g. scripts/collect-ground-truth.py --calibration bundle.json — on a JSON file that parses successfully but lacks one of the three required keys. The file itself is fine JSON; only the schema check fails.
Common situations: A hand-edited bundle where a section was renamed or removed; a bundle produced by an older version of the calibration tool before transceiver_geometry was added to the schema; passing a generic intrinsics-only JSON exported from another calibration tool instead of the two-checkerboard bundle.
Related errors
- {path}: each node needs 'id' and 'position_m' [x,y,z]
- manifest must be an object with a 'markers' array
- {path}: expected {{'nodes': [...]}} or a top-level list
- Intrinsics file {path} missing key {key!r}
- Failed to load domain configuration: {e}
AI-assisted analysis of ruvnet/RuView@4685618388 (2026-08-16).
Data as JSON: /api/errors/df93b8d092b8299f.
Report an issue: GitHub.