{"record":{"id":"d5f53b9c9352068c","repo":"ZhuLinsen/daily_stock_analysis","slug":"capability-unsupported-d5f53b","errorCode":"capability_unsupported","errorMessage":"Unsupported AGENT_BACKEND: {requested}","messagePattern":"Unsupported AGENT_BACKEND: (.+?)","errorType":"error_code","errorClass":"AgentBackendConfigError","httpStatus":null,"severity":"error","filePath":"src/agent/agent_backend.py","lineNumber":50,"sourceCode":"        \"unknown_backend_error\",\n    }\n)\nAGENT_BACKEND_IDS = frozenset({\"auto\", \"litellm\", \"codex_app_server\"})\n\n\nclass AgentBackendConfigError(ValueError):\n    \"\"\"Structured Agent backend selection error.\"\"\"\n\n    def __init__(self, code: str, message: str) -> None:\n        super().__init__(message)\n        self.code = code\n\n\ndef resolve_agent_backend_id(config: Any) -> str:\n    \"\"\"Resolve Chat backend; ``auto`` deliberately remains LiteLLM.\"\"\"\n    requested = str(getattr(config, \"agent_backend\", \"auto\") or \"auto\").strip().lower()\n    if requested not in AGENT_BACKEND_IDS:\n        raise AgentBackendConfigError(\n            \"capability_unsupported\",\n            f\"Unsupported AGENT_BACKEND: {requested}\",\n        )\n    return \"litellm\" if requested == \"auto\" else requested\n\n\n@dataclass(frozen=True)\nclass AgentRunRequest:\n    system_prompt: str\n    history_messages: List[Dict[str, Any]]\n    user_message: str\n    session_id: str\n    stock_scope: Optional[StockScope]\n    max_steps: int\n    max_wall_clock_seconds: Optional[float]\n    progress_callback: Optional[Callable[[Dict[str, Any]], None]] = None\n    cancel_event: Optional[threading.Event] = None\n","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/ZhuLinsen/daily_stock_analysis/blob/5159bd72e8373d215492dff122acc9d389e219c9/src/agent/agent_backend.py#L32-L68","documentation":"resolve_agent_backend_id validates config.agent_backend against the allowed set {auto, litellm, codex_app_server}; anything else raises AgentBackendConfigError with code 'capability_unsupported'. 'auto' resolves to litellm. The error is a structured ValueError carrying a machine-readable code for API layers to map to HTTP responses.","triggerScenarios":"Setting AGENT_BACKEND to an unsupported value such as 'openai', 'codex', 'codex-agent', or 'codex_appserver' (the codex value is 'codex_app_server', with underscores); whitespace/case are tolerated (.strip().lower()) but typos are not; empty string or None falls back to 'auto' safely.","commonSituations":"New deployment copying an env template with a stale backend name; users guessing 'codex' instead of 'codex_app_server'; API callers passing an arbitrary string through config construction without an enum check.","solutions":["Set AGENT_BACKEND to one of: auto, litellm, or codex_app_server (or unset it — default is auto/litellm).","If you intended the Codex path, fix the spelling to exactly codex_app_server.","Catch AgentBackendConfigError at the API boundary and inspect .code == 'capability_unsupported' to return a 4xx with the allowed values, instead of a generic 500.","If you are adding a new backend, register its id in AGENT_BACKEND_IDS (src/agent/agent_backend.py:35) rather than bypassing the check."],"exampleFix":"# before\n# .env\nAGENT_BACKEND=codex   # -> capability_unsupported\n\n# after\n# .env\nAGENT_BACKEND=codex_app_server","handlingStrategy":"type-guard","validationCode":"from src.agent.agent_backend import AGENT_BACKEND_IDS\n\nrequested = (config.agent_backend or \"auto\").strip().lower()\nassert requested in AGENT_BACKEND_IDS, f\"AGENT_BACKEND must be one of {sorted(AGENT_BACKEND_IDS)}\"","typeGuard":"def agent_backend_valid(value: str) -> bool:\n    return (value or \"auto\").strip().lower() in AGENT_BACKEND_IDS  # {'auto','litellm','codex_app_server'}","tryCatchPattern":"from src.agent.agent_backend import AgentBackendConfigError\n\ntry:\n    backend_id = resolve_agent_backend_id(config)\nexcept AgentBackendConfigError as e:\n    if e.code == \"capability_unsupported\":\n        return JSONResponse(status_code=400, content={\"error\": str(e), \"allowed\": sorted(AGENT_BACKEND_IDS)})\n    raise","preventionTips":["Document the exact allowed values (auto/litellm/codex_app_server) wherever AGENT_BACKEND is configured.","Validate at the API boundary and map capability_unsupported to 400, not 500.","Copy .env.example values verbatim; do not guess backend names like 'codex'."],"tags":["config","agent-backend","validation","enum"],"backgroundTag":null,"analyzedSha":"5159bd72e8373d215492dff122acc9d389e219c9","analyzedAt":"2026-08-15T01:59:36.292Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}