warpdotdev/warp · error

Expected {} field values, got {}

Error message

Expected {} field values, got {}

What it means

build_managed_secret_value requires field_values.len() to exactly equal info.fields.len(); the count check runs first, before any per-field validation. Optional fields still occupy a slot, so 'optional' does not mean 'omittable' in the vector.

Source

Thrown at app/src/ai/auth_secret_types.rs:49

    match harness {
        Harness::Claude => CLAUDE_LEARN_MORE_URL,
        Harness::Codex => CODEX_LEARN_MORE_URL,
        _ => DEFAULT_LEARN_MORE_URL,
    }
}

const DEFAULT_LEARN_MORE_URL: &str = "https://docs.warp.dev/platform/harnesses/authentication/";
const CODEX_LEARN_MORE_URL: &str =
    "https://docs.warp.dev/platform/harnesses/authentication/#connecting-codex-credentials";
const CLAUDE_LEARN_MORE_URL: &str =
    "https://docs.warp.dev/platform/harnesses/authentication/#connecting-claude-code-credentials";

pub fn build_managed_secret_value(
    info: &AuthSecretTypeInfo,
    field_values: &[String],
) -> Result<ManagedSecretValue> {
    if field_values.len() != info.fields.len() {
        return Err(anyhow!(
            "Expected {} field values, got {}",
            info.fields.len(),
            field_values.len()
        ));
    }
    for (field, value) in info.fields.iter().zip(field_values.iter()) {
        if !field.optional && value.trim().is_empty() {
            return Err(anyhow!("Field '{}' is required", field.label));
        }
    }
    match info.secret_type {
        ManagedSecretType::AnthropicApiKey => Ok(ManagedSecretValue::anthropic_api_key(
            field_values[0].clone(),
        )),
        ManagedSecretType::AnthropicBedrockApiKey => {
            Ok(ManagedSecretValue::anthropic_bedrock_api_key(
                field_values[0].clone(),
                field_values[1].clone(),

View on GitHub (pinned to e72fd7aacb)

Solutions

  1. Build field_values by iterating info.fields in order so lengths match by construction
  2. When an optional field is blank, still push an empty String placeholder
  3. Validate counts up front in the form layer before calling build_managed_secret_value
  4. After adding a field to AuthSecretTypeInfo, update every caller that constructs values

Example fix

// before
let value = build_managed_secret_value(&info, &[api_key])?; // OpenaiApiKey has 2 fields

// after
let field_values: Vec<String> = info
    .fields
    .iter()
    .map(|f| form.value_for(f).unwrap_or_default()) // always one entry per field
    .collect();
let value = build_managed_secret_value(&info, &field_values)?;
Defensive patterns

Strategy: validation

Validate before calling

debug_assert_eq!(field_values.len(), info.fields.len());
if field_values.len() != info.fields.len() {
    return Err(anyhow!("form produced {} values for {} fields", field_values.len(), info.fields.len()));
}

Type guard

fn arity_matches(info: &AuthSecretTypeInfo, values: &[String]) -> bool {
    values.len() == info.fields.len()
}

Prevention

When it happens

Trigger: Passing a form-built values slice whose length differs from info.fields.len() - e.g. 1 value for OpenaiApiKey which declares 2 fields (key + optional base_url), or 2 values for AnthropicApiKey which declares 1 (auth_secret_types.rs:48-53).

Common situations: UI hides the optional base_url input and submits only the key; a new field added to AuthSecretTypeInfo but the caller still submits the old count; reordering or filtering fields before zipping.

Related errors


AI-assisted analysis of warpdotdev/warp@e72fd7aacb (2026-08-16). Data as JSON: /api/errors/7a208597724333a2. Report an issue: GitHub.