HKUDS/Vibe-Trading · error · HTTPException

live runner is not supported for {broker}

Error message

live runner is not supported for {broker}

What it means

Thrown by the live-runner start endpoint when the requested broker does not support a persistent live runner, as determined by broker_supports_live_runner() in src.trading.service. It is a 400-level client error: the broker name is syntactically valid but is not in the set of brokers with live-runner support (paper-only or unsupported venues).

Source

Thrown at agent/src/api/live_routes.py:973

                    "supported for direct-SDK profiles"
                ),
            )

        report = h._check_connector_status(profile_id, force=force)
        return report

    @app.post("/live/runner/start", dependencies=[Depends(require_auth)])
    async def start_runner_endpoint(payload: LiveRunnerControlRequest):
        """Start the persistent live runner for a broker (SPEC §7.5)."""
        from src.live.halt import halt_flag_set
        from src.trading.service import broker_supports_live_runner

        broker = payload.broker.strip().lower()
        if not broker:
            raise HTTPException(status_code=400, detail="broker must not be blank")

        if not broker_supports_live_runner(broker):
            raise HTTPException(
                status_code=400,
                detail=f"live runner is not supported for {broker}",
            )

        h = _host()
        tasks = h._runner_tasks

        existing = tasks.get(broker)
        if existing is not None and not existing.done():
            return {"broker": broker, "started": False, "already_running": True}

        mandate = h._active_mandate_state(broker)
        if mandate is None:
            raise HTTPException(status_code=409, detail=f"no committed mandate for {broker}")
        if mandate.expired:
            raise HTTPException(status_code=409, detail=f"mandate for {broker} has expired; re-authorize first")
        if halt_flag_set(broker=broker) or halt_flag_set(broker=None):
            raise HTTPException(status_code=409, detail="kill switch is tripped; resume before starting the runner")

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Verify the exact broker identifier: check broker_supports_live_runner (src/trading/service.py) for the supported list and use one of those strings
  2. Strip/lowercase the broker name client-side — the endpoint does broker.strip().lower() but the value must still match a supported key
  3. If the broker should support live running, ensure the live runner adapter/credentials are configured and the broker is registered in the support map
  4. Fall back to non-runner endpoints (one-shot order placement) if you only need occasional execution

Example fix

// before
{"broker": "Paper"}
// after
{"broker": "alpaca"}
Defensive patterns

Strategy: validation

Validate before calling

from src.trading.service import broker_supports_live_runner
broker = payload['broker'].strip().lower()
if not broker_supports_live_runner(broker):
    raise ValueError(f'unsupported broker for live runner: {broker}')

Try / catch

catch HTTPException with status 400 and detail startswith 'live runner is not supported'; surface the supported broker list to the user instead of retrying

Prevention

When it happens

Trigger: POST to the live runner start endpoint with payload.broker set to a broker that broker_supports_live_runner() returns False for (e.g. a paper-trading-only broker, a typo like 'ibkr' vs 'interactive_brokers', or a broker only wired for quote/portfolio data).

Common situations: Broker naming mismatch after a config or version change, using a paper broker expecting live execution, or deploying against a backend where the broker adapter exists but live-runner support was never enabled.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/f5872edb51e7a543. Report an issue: GitHub.