usestrix/strix · error · TypeError
approved must be a boolean
Error message
approved must be a boolean
What it means
Raised by the TUI controller's _confirm_mount handler when the payload sent to confirm (or decline) a pending working-directory mount does not carry a strict boolean 'approved' field. Strix requires an explicit true/false decision because the mount confirmation is a security-relevant consent gate; any ambiguous value (string "true", 1, null, missing key) is rejected with a TypeError. This guards against frontend/IPC serialization bugs that would silently coerce the user's choice.
Source
Thrown at strix/interface/tui/backend/controller.py:350
if self._on_start is None:
raise RuntimeError("Scan start is unavailable")
self._start_in_progress = True
try:
await self._on_start(verify)
finally:
self._start_in_progress = False
self.setup_mode = False
self.scan_started = True
self.scan_state = "running"
async def _confirm_mount(self, payload: dict[str, Any]) -> dict[str, Any]:
"""Answer the pending working-directory mount asked for in the live view."""
mount = self.pending_workspace_mount
if mount is None:
raise RuntimeError("No mount confirmation is pending")
approved = payload.get("approved")
if not isinstance(approved, bool):
raise TypeError("approved must be a boolean")
self.pending_workspace_mount = None
# Declining skips the mount, it does not abandon the scan. The prompt is
# the whole of the input either way; the working directory is only an
# extra the agent may look at, so the run goes ahead without one.
self.workspace_mount = mount if approved else None
await self._begin_scan(self._pending_verify)
return {"approved": approved}
async def _send_message(self, payload: dict[str, Any]) -> dict[str, Any]:
agent_id = self._required_string(payload, "agent_id")
message = self._required_string(payload, "message")
if self.coordinator is None:
raise RuntimeError("Agent coordinator is unavailable")
if self.scan_loop is None or self.scan_loop.is_closed():
raise RuntimeError("Scan loop is not ready")
self.live_view.record_user_message(agent_id, message)
if self.scan_loop is asyncio.get_running_loop():
delivered = await self.coordinator.send(View on GitHub (pinned to 8551339130)
Solutions
- Send {"approved": true} or {"approved": false} as a real JSON boolean, not a string or integer
- Check the message schema in strix/interface/tui/backend/controller.py _confirm_mount and match the expected payload exactly
- In test harnesses, use json.loads('{"approved": true}') rather than hand-built dicts with coerced values
- If wrapping the controller, validate with isinstance(payload.get('approved'), bool) before dispatch
Example fix
// before
await controller.dispatch("confirm_mount", {"approved": "true"})
// after
await controller.dispatch("confirm_mount", {"approved": True}) Defensive patterns
Strategy: type-guard
Validate before calling
approved = payload.get("approved")
if not isinstance(approved, bool):
raise ValueError("payload['approved'] must be a JSON boolean") Type guard
def is_confirm_payload(p: dict) -> bool:
return isinstance(p.get("approved"), bool) Try / catch
try:
await controller.dispatch("confirm_mount", payload)
except TypeError as e:
if "approved must be a boolean" in str(e):
fix_payload_types() # coerce/repair then resend once Prevention
- Always send JSON booleans for approval flags; never strings or 0/1
- Centralize payload construction in one typed builder shared by UI and tests
- In test suites, assert isinstance(approved, bool) before dispatch
When it happens
Trigger: Calling the controller's confirm-mount command with payload {"approved": "true"}, {"approved": 1}, {"approved": null}, or omitting the key entirely while pending_workspace_mount is set. Typically happens when a custom TUI frontend or test harness JSON-encodes the flag as a non-bool type.
Common situations: Custom Bubble Tea/IPC clients serializing booleans as strings; test fixtures using 0/1 integers; payload builders that default missing values to None; protocol changes after upgrading Strix where the confirm message shape changed.
Related errors
- {name} must be a non-empty string
- instruction must be a string
- verify must be a boolean
- mount_working_dir must be a boolean
- No target set. Add a target first.
AI-assisted analysis of usestrix/strix@8551339130 (2026-08-15).
Data as JSON: /api/errors/8ec41d3773ff233d.
Report an issue: GitHub.