{"record":{"id":"bc132ab03fcc9ebf","repo":"jdx/mise","slug":"backends-must-not-be-empty","errorCode":null,"errorMessage":"backends must not be empty","messagePattern":"backends must not be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/registry.rs","lineNumber":418,"sourceCode":"        for alias in tool.aliases {\n            entries.insert((*alias).to_string(), tool.clone());\n        }\n    }\n    Ok(Registry::dynamic(entries, missing_version_order))\n}\n\nfn parse_registry_tool(short: &str, value: &toml::Value) -> Result<(RegistryTool, bool)> {\n    let table = value\n        .as_table()\n        .ok_or_else(|| eyre::eyre!(\"registry tool must be a TOML table\"))?;\n    let backends = table\n        .get(\"backends\")\n        .and_then(toml::Value::as_array)\n        .ok_or_else(|| eyre::eyre!(\"backends must be an array\"))?\n        .iter()\n        .map(parse_registry_backend)\n        .collect::<Result<Vec<_>>>()?;\n    ensure!(!backends.is_empty(), \"backends must not be empty\");\n\n    let missing_version_order = !table.contains_key(\"version_order\");\n    let version_order = match table.get(\"version_order\").and_then(toml::Value::as_str) {\n        Some(\"source\") => VersionOrder::Source,\n        Some(\"semver\") => VersionOrder::Semver,\n        Some(_) => bail!(\"version_order must be \\\"source\\\" or \\\"semver\\\"\"),\n        None => VersionOrder::Source,\n    };\n\n    ensure!(\n        version_order == VersionOrder::Semver || backends.iter().all(|b| b.min_version.is_none()),\n        \"backend min_version requires version_order = \\\"semver\\\"\"\n    );\n    let aliases = string_array(table.get(\"aliases\"), \"aliases\")?;\n    let bins = if table.contains_key(\"bins\") {\n        string_array(table.get(\"bins\"), \"bins\")?\n    } else {\n        BAKED_REGISTRY","sourceCodeStart":400,"sourceCodeEnd":436,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/registry.rs#L400-L436","documentation":"This error is thrown while parsing a registry tool's TOML table: after reading the 'backends' array (which itself must be present and an array), the loader requires the array to contain at least one backend. A tool declaration with an empty backends list is considered invalid because the tool would have no installable source.","triggerScenarios":"Defining a registry tool with `backends = []` in registry TOML, or constructing the array programmatically (e.g. via templating) such that it ends up empty.","commonSituations":"Commenting out or deleting all backend entries while leaving the empty array behind; template/CI generation that filters out all backends; copy-pasting a tool entry and removing backends before filling them in.","solutions":["Add at least one valid backend entry to the tool's backends array","Remove the tool entry entirely if it should not be in the registry","Check generated/templated registry files for filters that remove all backends"],"exampleFix":"// before\n[tools.node]\nbackends = []\n// after\n[tools.node]\nbackends = [\n  { backend = \"core\", ... }\n]","handlingStrategy":"validation","validationCode":"fn validate_backends(table: &toml::Value) -> Result<(), String> {\n    let arr = table.get(\"backends\").and_then(|v| v.as_array())\n        .ok_or(\"backends must be a non-empty array\")?;\n    if arr.is_empty() { return Err(\"backends must not be empty\".into()); }\n    Ok(())\n}","typeGuard":"fn has_backends(tool: &toml::Value) -> bool {\n    tool.get(\"backends\").and_then(|v| v.as_array()).map_or(false, |a| !a.is_empty())\n}","tryCatchPattern":null,"preventionTips":["Validate registry TOML in CI before merging changes","Don't leave empty arrays behind when commenting out backends — remove the tool entry","Check template generators never emit `backends = []`"],"tags":["registry","toml","validation","empty-array"],"backgroundTag":"empty-required-field","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}