tinyhumansai/openhuman · error · anyhow::Error
[claude_agent_sdk] error from claude CLI: {err}
Error message
[claude_agent_sdk] error from claude CLI: {err} What it means
While draining the claude CLI's NDJSON stdout, the provider received an explicit error message from the CLI itself — either a `Result` message with `is_error: true` or a top-level `Error` event (subprocess.rs:172-193). The subprocess completed; the failure is semantic (the CLI's agent turn failed), not a process or transport failure. The CLI's own error text is appended to the message.
Source
Thrown at src/openhuman/inference/provider/claude_agent_sdk/subprocess.rs:227
match read_result {
Ok(inner) => inner?,
Err(_) => {
let _ = child.kill().await;
anyhow::bail!("[claude_agent_sdk] subprocess timed out while reading output");
}
}
let status = timeout(Duration::from_secs(30), child.wait())
.await
.map_err(|_| {
anyhow::anyhow!("[claude_agent_sdk] subprocess timed out while waiting for exit")
})??;
let stderr_output = stderr_task.await.unwrap_or_default();
tracing::debug!("[claude_agent_sdk] subprocess exited status={}", status);
if let Some(err) = error_message {
anyhow::bail!("[claude_agent_sdk] error from claude CLI: {err}");
}
// Use the final result message if present; otherwise join streaming text parts.
let output = result_text
.filter(|s| !s.is_empty())
.unwrap_or_else(|| text_parts.join(""));
if !status.success() && output.is_empty() {
anyhow::bail!(
"[claude_agent_sdk] claude subprocess exited with non-zero status {} and no output; stderr={}",
status,
stderr_output
);
}
tracing::debug!(
"[claude_agent_sdk] response collected output_len={}",
output.len()View on GitHub (pinned to 7491200858)
Solutions
- Read the `{err}` text — it is the CLI's verbatim reason (e.g. 'credit balance too low', 'rate_limit_error') and determines the fix.
- For rate-limit/overload errors: retry with backoff; the failure is server-side and transient.
- For auth errors: run `claude login` (or set the API key env the CLI uses) in the same user context as the core.
- For request-shape errors (context too long): shrink the conversation or clear the session so the CLI starts a fresh context.
Defensive patterns
Strategy: try-catch
Try / catch
if let Err(e) = provider.chat(req).await {
let msg = e.to_string();
if msg.contains("error from claude CLI") {
// parse the trailing CLI text for rate_limit / credit / auth causes and branch
if msg.contains("rate_limit") || msg.contains("overloaded") {
backoff_retry(req).await;
} else {
surface_to_user(msg);
}
} else { return Err(e); }
} Prevention
- Keep the CLI logged in (`claude login`) in the same user context as the core process.
- Monitor quota/credits on the Anthropic account backing the CLI.
- Trim long conversations to avoid CLI-side context-overflow refusals.
When it happens
Trigger: The claude CLI returns an NDJSON result with `is_error` set (e.g. overloaded API, invalid request, credit/limit problem, disallowed tool use) or emits an `Error { message }` event. Any `chat` call routed to the claude_agent_sdk provider that ends in a CLI-side error.
Common situations: Anthropic API rate limits or 529 overloaded responses surfaced through the CLI, expired or invalid claude CLI login credentials, a prompt/request the CLI refuses (context overflow, forbidden tool), or quota exhaustion on the account.
Related errors
- [claude_agent_sdk] subprocess timed out while reading output
- Model testing is only available in the desktop app.
- Model test RPC returned no result for ${workload} via ${prov
- Local model runtime is unavailable in this core build. Resta
- [claude_agent_sdk] claude subprocess exited with non-zero st
AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17).
Data as JSON: /api/errors/a70913c2b290d1a3.
Report an issue: GitHub.