{"record":{"id":"9093f649ab9dd41f","repo":"zed-industries/zed","slug":"the-code-action-is-in-an-invalid-state-and-canno","errorCode":null,"errorMessage":"The `code_action` is in an invalid state and cannot be migrated at {}. Please ensure the code_action setting is a String","messagePattern":"The `code_action` is in an invalid state and cannot be migrated at (.+?)\\. Please ensure the code_action setting is a String","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/migrator/src/migrations/m_2025_10_16/settings.rs","lineNumber":49,"sourceCode":"\n    let Some(formatter) = obj.get(\"formatter\") else {\n        return Ok(());\n    };\n    let formatter_array = if let Some(array) = formatter.as_array() {\n        array.clone()\n    } else {\n        vec![formatter.clone()]\n    };\n    if formatter_array.is_empty() {\n        return Ok(());\n    }\n    let mut code_action_formatters = Vec::new();\n    for formatter in formatter_array {\n        let Some(code_action) = formatter.get(\"code_action\") else {\n            return Ok(());\n        };\n        let Some(code_action_name) = code_action.as_str() else {\n            anyhow::bail!(\n                r#\"The `code_action` is in an invalid state and cannot be migrated at {}. Please ensure the code_action setting is a String\"#,\n                fmt_path(path, \"formatter\"),\n            );\n        };\n        code_action_formatters.push(code_action_name.to_string());\n    }\n\n    code_actions_map.extend(\n        code_action_formatters\n            .into_iter()\n            .rev()\n            .map(|code_action| (code_action, Value::Bool(true))),\n    );\n\n    obj.insert(\"formatter\".to_string(), Value::Array(vec![]));\n    obj.insert(\n        \"code_actions_on_format\".into(),\n        Value::Object(code_actions_map),","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/zed-industries/zed/blob/f4178619acd0d47ea1f76a2025c42962c6d6638c/crates/migrator/src/migrations/m_2025_10_16/settings.rs#L31-L67","documentation":"Thrown by Zed's settings migrator (m_2025_10_16) while converting the legacy formatter `code_action` entries into the new `code_actions` map. For every element of a `formatter` array it expects `code_action` to be a JSON string naming a formatter (e.g. \"prettier\"); any other JSON type (object, number, bool, array, null) cannot be mapped, so the whole settings migration aborts and the message names the offending settings file path.","triggerScenarios":"A settings.json (user, project, or language entry) contains \"formatter\": [{ \"code_action\": { ... } }] or a number/boolean instead of a string, and Zed runs its startup settings migrations (or the migrator crate is invoked directly on that file).","commonSituations":"Hand-editing settings.json and nesting formatter options under code_action; pasting snippets from outdated docs or AI answers that model code_action as a structured value; an extension or profile writing a non-string value into a formatter entry.","solutions":["Open the settings file named in the error (the path is printed at the `formatter` key) and change the value to a plain string, e.g. \"code_action\": \"prettier\"","Remove the malformed `code_action` key entirely if no code-action formatter is wanted for that entry","Search every settings layer (user settings, project settings, language entries, profiles) for `code_action` and fix all non-string occurrences, then restart so migrations re-run"],"exampleFix":"// before\n\"formatter\": [{ \"code_action\": { \"name\": \"prettier\" } }]\n\n// after\n\"formatter\": [{ \"code_action\": \"prettier\" }]","handlingStrategy":"validation","validationCode":"fn formatter_entries_valid(value: &serde_json::Value) -> bool {\n    value.get(\"formatter\").map_or(true, |f| {\n        f.as_array().map_or(false, |entries| {\n            entries.iter().all(|e| {\n                e.get(\"code_action\").map_or(true, |ca| ca.is_string())\n            })\n        })\n    })\n}","typeGuard":"fn is_string_code_action(entry: &serde_json::Value) -> bool {\n    entry.get(\"code_action\").map_or(true, |ca| ca.is_string())\n}","tryCatchPattern":"match migrate(value) {\n    Err(err) if err.to_string().contains(\"code_action\") => {\n        eprintln!(\"fix the formatter code_action entry named in: {err}\");\n    }\n    rest => rest?,\n}","preventionTips":["Keep every code_action value a bare string formatter name, never a nested object","Lint settings.json (e.g. against Zed's JSON schema) before hand-editing","Avoid pasting formatter snippets from unverified sources; check the key's expected type first"],"tags":["zed","settings","migration","formatter","json-schema"],"backgroundTag":"settings-schema-validation-failed","analyzedSha":"f4178619acd0d47ea1f76a2025c42962c6d6638c","analyzedAt":"2026-08-20T19:29:52.058Z","contentChangedAt":"2026-08-20T19:29:52.058Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}