{"record":{"id":"7a208597724333a2","repo":"warpdotdev/warp","slug":"expected-field-values-got","errorCode":null,"errorMessage":"Expected {} field values, got {}","messagePattern":"Expected (.+?) field values, got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/src/ai/auth_secret_types.rs","lineNumber":49,"sourceCode":"    match harness {\n        Harness::Claude => CLAUDE_LEARN_MORE_URL,\n        Harness::Codex => CODEX_LEARN_MORE_URL,\n        _ => DEFAULT_LEARN_MORE_URL,\n    }\n}\n\nconst DEFAULT_LEARN_MORE_URL: &str = \"https://docs.warp.dev/platform/harnesses/authentication/\";\nconst CODEX_LEARN_MORE_URL: &str =\n    \"https://docs.warp.dev/platform/harnesses/authentication/#connecting-codex-credentials\";\nconst CLAUDE_LEARN_MORE_URL: &str =\n    \"https://docs.warp.dev/platform/harnesses/authentication/#connecting-claude-code-credentials\";\n\npub fn build_managed_secret_value(\n    info: &AuthSecretTypeInfo,\n    field_values: &[String],\n) -> Result<ManagedSecretValue> {\n    if field_values.len() != info.fields.len() {\n        return Err(anyhow!(\n            \"Expected {} field values, got {}\",\n            info.fields.len(),\n            field_values.len()\n        ));\n    }\n    for (field, value) in info.fields.iter().zip(field_values.iter()) {\n        if !field.optional && value.trim().is_empty() {\n            return Err(anyhow!(\"Field '{}' is required\", field.label));\n        }\n    }\n    match info.secret_type {\n        ManagedSecretType::AnthropicApiKey => Ok(ManagedSecretValue::anthropic_api_key(\n            field_values[0].clone(),\n        )),\n        ManagedSecretType::AnthropicBedrockApiKey => {\n            Ok(ManagedSecretValue::anthropic_bedrock_api_key(\n                field_values[0].clone(),\n                field_values[1].clone(),","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/warpdotdev/warp/blob/e72fd7aacbbb2236d9b3be2aad7e7178fe94b4bc/app/src/ai/auth_secret_types.rs#L31-L67","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Build field_values by iterating info.fields in order so lengths match by construction","When an optional field is blank, still push an empty String placeholder","Validate counts up front in the form layer before calling build_managed_secret_value","After adding a field to AuthSecretTypeInfo, update every caller that constructs values"],"exampleFix":"// before\nlet value = build_managed_secret_value(&info, &[api_key])?; // OpenaiApiKey has 2 fields\n\n// after\nlet field_values: Vec<String> = info\n    .fields\n    .iter()\n    .map(|f| form.value_for(f).unwrap_or_default()) // always one entry per field\n    .collect();\nlet value = build_managed_secret_value(&info, &field_values)?;","handlingStrategy":"validation","validationCode":"debug_assert_eq!(field_values.len(), info.fields.len());\nif field_values.len() != info.fields.len() {\n    return Err(anyhow!(\"form produced {} values for {} fields\", field_values.len(), info.fields.len()));\n}","typeGuard":"fn arity_matches(info: &AuthSecretTypeInfo, values: &[String]) -> bool {\n    values.len() == info.fields.len()\n}","tryCatchPattern":null,"preventionTips":["Generate form inputs from info.fields so the values vector matches by construction","Remember optional fields still need a (possibly empty) placeholder entry","When AuthSecretTypeInfo gains a field, grep all callers that build field_values"],"tags":["rust","warp","validation","auth","secrets"],"backgroundTag":null,"analyzedSha":"e72fd7aacbbb2236d9b3be2aad7e7178fe94b4bc","analyzedAt":"2026-08-16T08:27:25.381Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}