{"record":{"id":"64130ef9ae4672b0","repo":"usestrix/strix","slug":"verify-must-be-a-boolean","errorCode":null,"errorMessage":"verify must be a boolean","messagePattern":"verify must be a boolean","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"strix/interface/tui/backend/controller.py","lineNumber":305,"sourceCode":"        return {\"target\": target, \"total\": len(self.targets)}\n\n    async def _set_instruction(self, payload: dict[str, Any]) -> dict[str, Any]:\n        self._require_setup_mutable()\n        instruction = payload.get(\"instruction\", \"\")\n        if not isinstance(instruction, str):\n            raise TypeError(\"instruction must be a string\")\n        self.instruction = instruction.strip()\n        return {\"instruction\": self.instruction}\n\n    async def _start(self, payload: dict[str, Any]) -> dict[str, Any]:\n        if self.scan_started or self._start_in_progress:\n            raise RuntimeError(\"Scan is already starting or running\")\n        # A bare prompt launches optimistically, like a coding agent: it skips\n        # the network model preflight and surfaces any model error live. A named\n        # target keeps the preflight so a real scan does not commit blind.\n        verify = payload.get(\"verify\", True)\n        if not isinstance(verify, bool):\n            raise TypeError(\"verify must be a boolean\")\n        # Launching with no target mounts the working directory, so it requires\n        # the user's explicit confirmation rather than happening silently.\n        mount_working_dir = payload.get(\"mount_working_dir\", False)\n        if not isinstance(mount_working_dir, bool):\n            raise TypeError(\"mount_working_dir must be a boolean\")\n        model = (load_settings().llm.model or \"\").strip()\n        if not model:\n            raise ValueError(\"No model configured. Set STRIX_LLM first.\")\n        if self._on_start is None:\n            raise RuntimeError(\"Scan start is unavailable\")\n        if not self.targets:\n            if not mount_working_dir:\n                raise ValueError(\"No target set. Add a target first.\")\n            # Mounting the working directory needs the user's confirmation, and\n            # that is asked in the live view. Enter it now and prepare nothing\n            # until the answer arrives, so declining leaves no run behind.\n            self.pending_workspace_mount = str(Path.cwd())\n            self._pending_verify = verify","sourceCodeStart":287,"sourceCodeEnd":323,"githubUrl":"https://github.com/usestrix/strix/blob/85513391305171ecc6faffe03da4a8bda5e3febb/strix/interface/tui/backend/controller.py#L287-L323","documentation":"Raised by _start in the TUI controller (strix/interface/tui/backend/controller.py:305) when the optional 'verify' payload field (default true, controlling the network model preflight) is present but not a bool. JSON is the transport, so numbers/strings like 1 or 'true' do not count as booleans; the isinstance(verify, bool) check enforces strict typing at the trust boundary.","triggerScenarios":"Sending payload {\"verify\": 1}, {\"verify\": \"true\"}, or {\"verify\": null} with setup.start; frontends normalizing checkbox values to 0/1; YAML-driven scripts parsing unquoted true/false as strings.","commonSituations":"JS frontends sending truthy integers; config-driven automation where booleans arrive as strings from CLI flags.","solutions":["Send an actual JSON boolean: {\"verify\": false}; omit the field entirely to accept the default true.","Coerce at the source: Boolean(value) in JS, bool(value) in Python before dispatch.","Add a payload schema check in the frontend tests."],"exampleFix":"# before\nawait controller.handle(\"setup.start\", {\"verify\": 1})\n\n# after\nawait controller.handle(\"setup.start\", {\"verify\": True})","handlingStrategy":"type-guard","validationCode":"verify = payload.get(\"verify\", True)\nif not isinstance(verify, bool):\n    payload[\"verify\"] = bool(verify)  # or reject before dispatch","typeGuard":"def has_boolean_verify(payload: dict) -> bool:\n    return \"verify\" not in payload or isinstance(payload[\"verify\"], bool)","tryCatchPattern":"try:\n    await controller.handle(\"setup.start\", payload)\nexcept TypeError as exc:\n    if 'verify must be a boolean' in str(exc):\n        payload[\"verify\"] = bool(payload[\"verify\"])\n        await controller.handle(\"setup.start\", payload)\n    else:\n        raise","preventionTips":["Always send JSON true/false, never 1/0 or \"true\".","Map UI checkboxes directly to booleans.","Omit optional flags to take defaults."],"tags":["tui","type-validation","payload","boolean"],"backgroundTag":null,"analyzedSha":"85513391305171ecc6faffe03da4a8bda5e3febb","analyzedAt":"2026-08-15T05:03:57.275Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}