BerriAI/litellm · error · ValueError

WXO: No run_id in response: {run_data}

Error message

WXO: No run_id in response: {run_data}

What it means

Raised by LiteLLM's watsonx Orchestrate (WXO) A2A handler when a run-submission response has a non-terminal status but carries neither a 'run_id' nor an 'id' field. The handler needs a run id to poll the run to completion via _poll_run, so without it the flow cannot continue and a ValueError is raised. This almost always indicates an unexpected/changed WXO API response shape (e.g. an error payload that still reports a running status).

Source

Thrown at litellm/a2a_protocol/providers/watsonx_orchestrate/handler.py:157

            if status in WatsonxOrchestrateTransformation.TERMINAL_STATES:
                return result

        raise asyncio.TimeoutError(
            f"WXO run '{run_id}' did not reach a terminal state after {max_attempts * interval_s:.0f}s"
        )

    @staticmethod
    async def _get_successful_run_data(
        run_data: dict[str, Any],
        base_url: str,
        auth_headers: dict[str, str],
        client: AsyncHTTPHandler,
    ) -> dict[str, Any]:
        status = run_data.get("status", "")
        if status not in WatsonxOrchestrateTransformation.TERMINAL_STATES:
            run_id: Final = run_data.get("run_id") or run_data.get("id") or ""
            if not run_id:
                raise ValueError(f"WXO: No run_id in response: {run_data}")
            run_data = await WatsonxOrchestrateHandler._poll_run(
                base_url=base_url,
                run_id=run_id,
                auth_headers=auth_headers,
                client=client,
            )
            status = run_data.get("status", "")

        if status not in WatsonxOrchestrateTransformation.SUCCESS_STATES:
            raise RuntimeError(f"WXO run ended with non-success status '{status}': {run_data}")

        return run_data

    @staticmethod
    async def _accumulate_wxo_sse_text(response: Any) -> str:
        accumulated_text = ""
        async for line in response.aiter_lines():
            if not line.startswith("data:"):

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Log the full run_data payload (already embedded in the exception message) and compare its keys against the expected WXO run response to spot schema drift or an error body.
  2. Verify cp4d_host, instance_id and wxo_agent_id in litellm_params resolve to the correct watsonx Orchestrate endpoint for your CP4D version.
  3. If your WXO version returns the id under a different key, patch _get_successful_run_data to include that key in the run_id fallback chain and open an issue upstream with the response sample.

Example fix

// before
run_id = run_data.get("run_id") or run_data.get("id") or ""
if not run_id:
    raise ValueError(f"WXO: No run_id in response: {run_data}")

// after (also accept alternate id field)
run_id = run_data.get("run_id") or run_data.get("id") or run_data.get("runId") or ""
if not run_id:
    raise ValueError(f"WXO: No run_id in response: {run_data}")
Defensive patterns

Strategy: try-catch

Validate before calling

def has_run_id(run_data: dict) -> bool:
    return bool(run_data.get("run_id") or run_data.get("id"))

Type guard

def is_pollable_wxo_response(run_data: dict) -> bool:
    status = run_data.get("status", "")
    return status in TERMINAL_STATES or bool(run_data.get("run_id") or run_data.get("id"))

Try / catch

try:
    result = await wxo_call(...)
except ValueError as e:
    if "No run_id" in str(e):
        logger.error("WXO response missing run id; dump payload for schema inspection: %s", e)
        raise WXOSchemaError(str(e)) from e
    raise

Prevention

When it happens

Trigger: Calling an WXO agent through LiteLLM's a2a_protocol where the initial run response dict lacks both 'run_id' and 'id' keys (or both are empty/None) while 'status' is not in TERMINAL_STATES. Typical causes: wrong endpoint/version of watsonx Orchestrate, an error body masquerading as a run, or a proxy returning an HTML error page parsed as JSON.

Common situations: watsonx Orchestrate on Cloud Pak for Data upgraded to a version with a changed response schema; cp4d_host/instance_id pointing to the wrong service path so the API returns an unexpected body; authentication middleware returning a JSON error without a run id.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/4b147965f2ce9297. Report an issue: GitHub.