gitbutlerapp/gitbutler · error · anyhow::Error

{field} is required

Error message

{field} is required

What it means

`required_message` is the shared guard for required string fields on the AI NAPI surface: it trims the input and rejects empty or whitespace-only strings with '<field> is required', naming the offending field. It runs before any request is dispatched to the provider.

Source

Thrown at crates/but-napi/src/ai.rs:275

                }
            },
        )?;
        response
            .filter(|response| !response.trim().is_empty())
            .context("AI provider returned an empty response")
    })
    .await
    .context("AI response task failed")
    .and_then(|result| result)
    .map_err(to_napi_err)?;

    Ok(response)
}

fn required_message<'a>(value: &'a str, field: &str) -> Result<&'a str> {
    let value = value.trim();
    if value.is_empty() {
        bail!("{field} is required")
    }
    Ok(value)
}

#[cfg(test)]
mod tests {
    use super::*;
    use but_llm::{
        AI_LMSTUDIO_MODEL_NAME_KEY, AI_MODEL_PROVIDER_KEY, AI_OPENAI_CUSTOM_ENDPOINT_KEY,
        DEFAULT_ANTHROPIC_MODEL, DEFAULT_LMSTUDIO_ENDPOINT, DEFAULT_LMSTUDIO_MODEL,
        DEFAULT_OLLAMA_ENDPOINT, DEFAULT_OLLAMA_MODEL, DEFAULT_OPENAI_MODEL,
    };

    fn valid_update() -> AiConfigurationUpdate {
        AiConfigurationUpdate {
            provider: "openai".into(),
            openai_key_option: "butlerAPI".into(),
            openai_model: DEFAULT_OPENAI_MODEL.into(),

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Pass a value that is non-empty after trimming for the field named in the message
  2. Disable submit in the UI until required fields are filled
  3. Trim client-side and treat whitespace-only as empty

Example fix

// before
await ai.request({ message: '   ' }); // bails: message is required

// after
const message = messageInput.trim();
if (!message) throw new Error('Message is required');
await ai.request({ message });
Defensive patterns

Strategy: validation

Validate before calling

// TypeScript: enforce non-empty required fields before calling native code
function requireNonEmpty(value: string | undefined, field: string): string {
  const v = (value ?? '').trim();
  if (!v) throw new Error(`${field} is required`);
  return v;
}
await ai.request({ message: requireNonEmpty(input.message, 'Message') });

Type guard

// TypeScript
const isNonEmpty = (v?: string | null): boolean => !!v && v.trim().length > 0;

Try / catch

Catch the error, parse the '<field> is required' message, and focus/highlight the named field in the UI.

Prevention

When it happens

Trigger: Calling an AI entry point in but-napi ai.rs with a required string argument that trims to empty — for example an untouched form submitting an empty message/prompt.

Common situations: UI submitting before the user types anything; whitespace-only input produced by templating; optional-vs-required field mismatch between frontend and native module versions.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/b003287f0a7bfa2e. Report an issue: GitHub.