Hmbown/CodeWhale · error
permission_posture must not be empty
Error message
permission_posture must not be empty
What it means
When a thread-update request includes a `permission_posture`, the value must not be empty or whitespace-only. The posture drives permission decisions for the thread, so a blank value would silently disable or corrupt permission policy.
Solutions
- Pass `None` to leave the current posture unchanged.
- Use one of the library's named postures rather than a free-form string.
- Trim-and-drop or validate against the supported posture set before sending.
Example fix
// before
UpdateThreadRequest { permission_posture: Some(posture), .. } // may be ""
// after
UpdateThreadRequest { permission_posture: Some(posture).filter(|p| !p.trim().is_empty()), .. } Defensive patterns
Strategy: validation
Validate before calling
if let Some(p) = &req.permission_posture { if p.trim().is_empty() { req.permission_posture = None; } } Type guard
fn valid_posture(p: &str) -> bool { !p.trim().is_empty() } Prevention
- Use the library's named posture constants instead of free strings
- Validate posture against supported values before the call
- Treat blank input as 'unchanged' and omit the field
When it happens
Trigger: Calling update-thread with `permission_posture: Some("".into())` or a whitespace-only string; a client sends `{"permission_posture": ""}`.
Common situations: A settings UI clears a posture dropdown; automation copies an empty posture field from another thread; a config merge produces empty strings for unset enum-like fields.
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
- append_allow_rules only accepts action = "allow"
- empty key text
- fleet task ' ' is write-capable but declares no…
- mode must not be empty
- model must not be empty
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/8fd36ed9e616ee1e.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/runtime_threads.rs:7892
&& req.workspace.is_none()
{
bail!("At least one thread field is required");
}
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 {
NoneView on GitHub (pinned to 73e0f67d83)