HKUDS/Vibe-Trading · error · LiveRunnerUnavailable
live runner for {broker!r} does not define remote tool {oper
Error message
live runner for {broker!r} does not define remote tool {operation!r} What it means
Raised by LiveRunnerUnavailable when the helper _tool() cannot map a broker's operation (e.g. 'positions' or 'account') to a remote tool name via runner_tool_name(broker, operation). This happens during _build_live_runner, meaning the selected broker's live runner contract has no registered tool for that operation — typically a registration/mapping gap in src/trading/service.py or an unsupported broker slipped through earlier validation.
Source
Thrown at agent/src/api/live_routes.py:554
"""
h = _host()
# _runner_factory is monkeypatched on host by tests
factory = getattr(h, "_runner_factory", None)
if factory is not None:
return factory(broker)
from src.live.audit import write_live_action
from src.live.runtime.reconcile import reconcile
from src.live.runtime.runner import LiveRunner
from src.live.runtime.scheduler import Scheduler
from src.live.runtime.triggers import Trigger
from src.trading.service import runner_tool_name
def _tool(operation: str) -> str:
remote_tool = runner_tool_name(broker, operation)
if remote_tool is None:
raise LiveRunnerUnavailable(
f"live runner for {broker!r} does not define remote tool {operation!r}"
)
return remote_tool
positions_tool = _tool("positions")
balance_tool = _tool("account")
open_orders_tool = _tool("orders")
submit_order_tool = _tool("submit_order")
cancel_order_tool = _tool("cancel_order")
# _live_broker_adapter is monkeypatched on host by tests
adapter = h._live_broker_adapter(broker)
def _read(remote_tool: str):
return lambda: adapter.call_tool(remote_tool, {})
def _submit(order: Dict[str, Any]) -> Dict[str, Any]:
if order.get("action") == "cancel":View on GitHub (pinned to 80ffdda44c)
Solutions
- Check runner_tool_name in src/trading/service.py and confirm the broker/operation pair is registered
- Add the missing mapping entry for the broker's 'positions' and 'account' tools
- If the broker genuinely lacks an operation, gate the endpoint earlier with a 400 'not supported' instead of building the runner
- Retry after upgrading/redeploying so agent and runner versions match
Example fix
// before (src/trading/service.py)
RUNNER_TOOLS = {"ibkr": {"positions": "ibkr_positions", "account": "ibkr_account"}}
// after
RUNNER_TOOLS = {
"ibkr": {"positions": "ibkr_positions", "account": "ibkr_account"},
"tradier": {"positions": "tradier_positions", "account": "tradier_balances"},
} Defensive patterns
Strategy: validation
Validate before calling
from src.trading.service import runner_tool_name
def can_build_runner(broker: str, ops=("positions", "account")) -> bool:
return all(runner_tool_name(broker, op) is not None for op in ops) Type guard
def has_runner_tools(broker: str) -> bool:
from src.trading.service import runner_tool_name
return runner_tool_name(broker, 'positions') is not None and runner_tool_name(broker, 'account') is not None Try / catch
try:
runner = _build_live_runner(broker)
except LiveRunnerUnavailable as e:
logger.warning('runner tools missing for %s: %s', broker, e)
return JSONResponse(status_code=501, content={'detail': str(e)}) Prevention
- Register positions/account tool names whenever adding a broker runner
- Add a startup check that every known live broker maps all required operations
- Pin agent and runner versions together in deploys
When it happens
Trigger: Calling any live endpoint that builds a live runner for a broker whose runner_tool_name(broker, 'positions') or (broker, 'account') returns None — e.g. GET /live/status?broker=<new-broker> after adding a broker connector without registering its remote tool names.
Common situations: Adding a new broker's live runner but forgetting to add its tool-name mapping; renaming operations in the runner registry without updating runner_tool_name; version skew between the agent API and the runner definitions.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- no MCP server configured for live broker {broker!r}
- live runner is not supported for {broker}
- no committed mandate for {broker}
- mandate for {broker} has expired; re-authorize first
- live trading or execution goals are not supported
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/39fd9e12f9a21a73.
Report an issue: GitHub.