usestrix/strix · warning · RuntimeError

Setup can no longer be changed after the scan starts

Error message

Setup can no longer be changed after the scan starts

What it means

Raised by _require_setup_mutable (controller.py:488) when a setup-mutating command (changing targets, options, credentials) arrives after the setup phase ended. The guard trips when setup_mode is false, or scan_started is true, or _start_in_progress is true — any of these makes configuration immutable. Strix freezes configuration at scan start so the running scan cannot observe mid-flight config changes.

Source

Thrown at strix/interface/tui/backend/controller.py:488

            httpd.server_close()

    async def _quit(self, _payload: dict[str, Any]) -> dict[str, Any]:
        self.close_viewer()
        if self._on_quit is not None:
            await self._on_quit()
        self.scan_state = "stopped"
        return {"quitting": True}

    @staticmethod
    def _required_string(payload: dict[str, Any], name: str) -> str:
        value = payload.get(name)
        if not isinstance(value, str) or not value.strip():
            raise ValueError(f"{name} must be a non-empty string")
        return value.strip()

    def _require_setup_mutable(self) -> None:
        if not self.setup_mode or self.scan_started or self._start_in_progress:
            raise RuntimeError("Setup can no longer be changed after the scan starts")

View on GitHub (pinned to 8551339130)

Solutions

  1. Treat setup as locked once start is clicked: disable setup controls on _start_in_progress
  2. To change configuration, quit and start a new scan session
  3. Check controller.setup_mode / scan_started before sending setup commands
  4. In automation, complete all configuration before invoking the start command

Example fix

# before
await controller._set_target({"target": "https://example.com"})  # after start

# after
if controller.setup_mode and not controller.scan_started:
    await controller._set_target({"target": "https://example.com"})
else:
    logging.warning("setup locked; restart the scan to reconfigure")
Defensive patterns

Strategy: validation

Validate before calling

if not controller.setup_mode or controller.scan_started or controller._start_in_progress:
    raise RuntimeError("setup locked; restart the scan to reconfigure")

Type guard

def setup_mutable(c) -> bool:
    return c.setup_mode and not c.scan_started and not c._start_in_progress

Try / catch

try:
    await controller.dispatch(setup_command, payload)
except RuntimeError as e:
    if "Setup can no longer be changed" in str(e):
        prompt_restart_session()
    else:
        raise

Prevention

When it happens

Trigger: Calling any setup-mutating handler (target add/remove, option change) after 'Start scan' was pressed (_start_in_progress or scan_started), or after setup_mode was cleared. Includes the window between clicking start and the scan actually launching.

Common situations: UI lets the user edit the target list while the scan is starting; late-arriving keystrokes queued before start; users trying to retarget a running scan instead of restarting it; race where the setup screen is still rendered but the start already fired.

Related errors


AI-assisted analysis of usestrix/strix@8551339130 (2026-08-15). Data as JSON: /api/errors/11a05a89f393e7df. Report an issue: GitHub.