Hmbown/CodeWhale · error

At least one thread field is required

Error message

At least one thread field is required

What it means

The thread-update request validates that at least one field is actually set (`model`, `mode`, `permission_posture`, `title`, `system_prompt`, `workspace`, etc.). A request where every optional field is `None` is a no-op and is rejected instead of silently doing nothing.

Solutions

  1. Set at least one field on the request before calling update (e.g. `title: Some(...)` or `model: Some(...)`).
  2. On the caller side, check the built request for all-empty fields and skip the API call entirely.
  3. If the intent is a read, use the get-thread API instead of a no-op update.

Example fix

// before
let req = UpdateThreadRequest::default();
api.update_thread(id, req).await?; // Err: At least one thread field is required

// after
let req = UpdateThreadRequest { title: Some("New title".into()), ..Default::default() };
if req.has_any_field() {
    api.update_thread(id, req).await?;
}
Defensive patterns

Strategy: validation

Validate before calling

if req.model.is_none() && req.mode.is_none() && req.permission_posture.is_none()
    && req.title.is_none() && req.system_prompt.is_none() && req.workspace.is_none()
    && req.allow_shell.is_none() {
    return; // skip the no-op update entirely
}

Type guard

fn has_any_field(req: &UpdateThreadRequest) -> bool {
    req.model.is_some() || req.mode.is_some() || req.permission_posture.is_some()
        || req.title.is_some() || req.system_prompt.is_some() || req.workspace.is_some()
}

Prevention

When it happens

Trigger: Calling the update-thread API with an entirely empty/default request struct — all `Option` fields left as `None` (e.g. deserialized from an empty JSON object `{}`).

Common situations: A PATCH-style HTTP client sends `{}` as the body; a frontend builds the request object conditionally and all conditions are false; a caller constructs `UpdateThreadRequest::default()`.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/871baa7f90f12691. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/runtime_threads.rs:7876

        id: &str,
        req: UpdateThreadRequest,
        config_path: Option<&Path>,
        config_profile: Option<&str>,
    ) -> Result<ThreadRecord> {
        // Keep policy publication ordered with this authorization decision.
        let _config_admission = self.config_admission.read().await;
        if req.archived.is_none()
            && req.allow_shell.is_none()
            && req.trust_mode.is_none()
            && req.auto_approve.is_none()
            && req.model.is_none()
            && req.mode.is_none()
            && req.permission_posture.is_none()
            && req.title.is_none()
            && req.system_prompt.is_none()
            && 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()

View on GitHub (pinned to 73e0f67d83)