Hmbown/CodeWhale · error · anyhow::Error
runtime API returned {status}
Error message
runtime API returned {status} What it means
SessionManager normalizes its managed (sessions) directory before use: normalize_managed_dir rejects an empty path immediately with InvalidInput - an empty OsString cannot name a directory - then rejects relative paths containing traversal components, and finally anchors plain relative paths to the current directory.
Source
Thrown at crates/app-server/src/lib.rs:1109
}
}
}
fn authed(&self, builder: reqwest::RequestBuilder) -> reqwest::RequestBuilder {
match self.auth_token.as_deref() {
Some(token) => builder.bearer_auth(token),
None => builder,
}
}
async fn request_json(&self, builder: reqwest::RequestBuilder) -> Result<Value> {
let response = builder.send().await?;
let status = response.status();
let body = response.text().await?;
if !status.is_success() {
let detail = body.trim();
if detail.is_empty() {
bail!("runtime API returned {status}");
}
bail!("runtime API returned {status}: {detail}");
}
serde_json::from_str(&body).with_context(|| format!("invalid runtime API json: {body}"))
}
async fn ensure_runtime_thread(
&mut self,
stdio_thread_id: &str,
hint: Option<RuntimeThreadHint>,
) -> Result<String> {
if let Some(runtime_thread_id) = self.thread_map.get(stdio_thread_id) {
return Ok(runtime_thread_id.clone());
}
let hint = hint.unwrap_or_default();
let runtime_thread_id = self
.create_runtime_thread(hint.model, hint.workspace)
.await?;View on GitHub (pinned to 0c42157ee5)
Solutions
- Set sessions_dir to a real path, or remove the empty override so the built-in default applies
- Replace unwrap_or_default() with unwrap_or_else(default_sessions_dir) for optional path settings
- Validate path-valued config at load time and reject blank strings with a clear field name
Example fix
// before let dir = cfg.sessions_dir.clone().unwrap_or_default(); // after let dir = cfg.sessions_dir.clone().unwrap_or_else(default_sessions_dir);
Defensive patterns
Strategy: validation
Validate before calling
fn managed_dir_is_valid(p: &std::path::Path) -> bool {
!p.as_os_str().is_empty()
} Type guard
fn is_non_empty_dir_path(p: &std::path::Path) -> bool { !p.as_os_str().is_empty() } Try / catch
match normalize_managed_dir(dir.clone()) {
Err(e) if e.to_string().contains("cannot be empty") => {
// fail config load naming the sessions_dir field; require a real path or the default
}
other => other?,
} Prevention
- Reject blank strings for path-valued config keys at load time
- Use unwrap_or_else(default_dir), never unwrap_or_default(), for optional paths
- Trim and validate env-var overrides before they become directories
When it happens
Trigger: Constructing SessionManager (which calls normalize_managed_dir at session_manager.rs:1022) with an empty sessions_dir PathBuf: a config value like sessions_dir = "", a blank environment override, or Option::unwrap_or_default() on a missing setting (PathBuf's default is empty).
Common situations: Config templating that leaves a path key present but blank; env var set to an empty string; code defaulting a missing optional path to PathBuf::new() instead of a real default directory.
Related errors
- parallel(): max 1000 items per call
- This browser session is not authenticated. Restart `codewhal
- max_chars must be > 0
- Codewhale account API base URL must not contain a query or f
- Codewhale account API base URL must be an origin without a p
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/dcefd1caf719c807.
Report an issue: GitHub.