Hmbown/CodeWhale · error
workspace must not be empty
Error message
workspace must not be empty
What it means
When a thread-update request includes a `workspace`, the path must not be the empty path (`PathBuf::new()` / empty OsStr). The workspace anchors the thread's file access and shell policy, so an empty workspace would be meaningless or unsafe.
Solutions
- Pass `None` for `workspace` to keep the current workspace.
- Resolve the workspace to a real absolute directory path before the call.
- On the client side, treat empty-string workspace as absent and omit the field.
Example fix
// before
UpdateThreadRequest { workspace: Some(PathBuf::from(ws_str)), .. } // ws_str may be ""
// after
UpdateThreadRequest {
workspace: if ws_str.trim().is_empty() { None } else { Some(PathBuf::from(ws_str)) },
..
} Defensive patterns
Strategy: validation
Validate before calling
if let Some(ws) = &req.workspace { if ws.as_os_str().is_empty() { req.workspace = None; } } Type guard
fn valid_workspace(ws: &Option<PathBuf>) -> bool {
ws.as_ref().map_or(true, |p| !p.as_os_str().is_empty())
} Prevention
- Resolve workspace paths to absolute existing directories before updates
- Map empty-string workspaces to None when deserializing
- Verify the directory exists (canonicalize) before assigning it to a thread
When it happens
Trigger: Calling update-thread with `workspace: Some(PathBuf::new())`; a JSON body with `"workspace": ""` deserialized into an empty PathBuf.
Common situations: A client strips the workspace field to "" when clearing it; a path variable never got assigned before the call; deserializing an empty string from config into `Option<PathBuf>` yields Some(empty).
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- project workspace path cannot be empty
- workspace path cannot be empty
- workspace path cannot contain '..' components
- AutomationEditorInvalidWorkspace
- budget baseline_receipt path changed
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/f75c0624b12bb8d6.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/runtime_threads.rs:7897
if let Some(model) = req.model.as_ref()
&& model.trim().is_empty()
{
bail!("model must not be empty");
}
if let Some(mode) = req.mode.as_ref()
&& mode.trim().is_empty()
{
bail!("mode must not be empty");
}
if let Some(permission_posture) = req.permission_posture.as_ref()
&& permission_posture.trim().is_empty()
{
bail!("permission_posture must not be empty");
}
if let Some(workspace) = req.workspace.as_ref()
&& workspace.as_os_str().is_empty()
{
bail!("workspace must not be empty");
}
// Source resolution reads config files. Do it off the Tokio worker,
// then recheck the conversation identity before committing the grant.
let shell_policy_workspace = if req.allow_shell == Some(true) || req.workspace.is_some() {
let current = self.get_thread(id).await?;
if req.allow_shell.unwrap_or(current.allow_shell) {
let workspace = req.workspace.clone().unwrap_or(current.workspace);
self.validate_shell_access_policy(&workspace, config_path, config_profile)
.await?;
Some(workspace)
} else {
None
}
} else {
None
};
let configured_sandbox_mode = self.read_config().sandbox_mode.clone();View on GitHub (pinned to 73e0f67d83)