HKUDS/DeepTutor · error · LLMAPIError
Cohere API error: unexpected response payload
Error message
Cohere API error: unexpected response payload
What it means
After a 200 response, _cohere_complete expects result['text'] to be a string; any other top-level shape (missing 'text', nested generations, error object returned with 200) triggers LLMAPIError 'unexpected response payload'. It is the Cohere analogue of the schema-drift guard: status was fine, payload was not.
Source
Thrown at deeptutor/services/llm/cloud_provider.py:865
timeout = aiohttp.ClientTimeout(total=120)
connector = _get_aiohttp_connector()
async with aiohttp.ClientSession(
timeout=timeout, connector=connector, trust_env=True
) as session:
async with session.post(url, headers=headers, json=data) as response:
if response.status != 200:
error_text = await response.text()
raise LLMAPIError(
f"Cohere API error: {error_text}",
status_code=response.status,
provider="cohere",
)
result = cast(dict[str, object], await response.json())
text = result.get("text")
if isinstance(text, str):
return text
raise LLMAPIError(
"Cohere API error: unexpected response payload",
status_code=response.status,
provider="cohere",
)
async def fetch_models(
base_url: str,
api_key: str | None = None,
binding: str = "openai",
) -> list[str]:
"""
Fetch available models from cloud provider.
Args:
base_url: API endpoint URL
api_key: API key
binding: Provider type (openai, anthropic)View on GitHub (pinned to 3e82f13042)
Solutions
- Log the raw JSON body to see which shape is returned.
- Point base_url at the endpoint version whose schema this code expects (text field), or adapt parsing upstream.
- Fix mock fixtures to include a top-level "text" string.
- Check for provider middleware rewriting bodies.
Example fix
// before
# stub response
{"generations": [{"text": "hi"}]}
# after
{"text": "hi"} Defensive patterns
Strategy: type-guard
Validate before calling
# Not applicable (server payload); ensure the endpoint returns the legacy shape: # assert base_url in known_v1_endpoints
Type guard
def is_cohere_text_payload(result: dict) -> bool:
return isinstance(result.get("text"), str) Try / catch
try:
out = await complete(prompt=p, binding="cohere", model=m, api_key=k)
except LLMAPIError as e:
if "unexpected response payload" in str(e):
log.error("endpoint returned non-v1 Cohere shape; check base_url")
raise Prevention
- Pin the Cohere endpoint version your parser targets in base_url.
- Type-check mock fixtures include a top-level 'text' string.
- Watch Cohere release notes for schema changes (v1 generate vs v2 chat).
When it happens
Trigger: Endpoint returns the newer Cohere v2 shape ({message: {content: [...]}}) instead of the legacy {text}; a proxy normalizes responses differently; mock fixtures missing the text key; model variants that return generations arrays.
Common situations: Cohere API version drift between v1 generate and v2 chat endpoints; hand-written test stubs; gateways aggregating multiple providers into one schema.
Related errors
- Anthropic API error: unexpected response payload
- Cloud completion failed: no valid configuration
- Cohere API key is missing from the active LLM profile.
- Cohere API error: {error_text}
- This model is not assigned to your account.
AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27).
Data as JSON: /api/errors/cc4ca02949810e0b.
Report an issue: GitHub.