{"record":{"id":"4ef0d1771990cd08","repo":"jdx/mise","slug":"bootstrap-compose-project-names-cannot-be-empty","errorCode":null,"errorMessage":"bootstrap compose project names cannot be empty","messagePattern":"bootstrap compose project names cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/compose.rs","lineNumber":315,"sourceCode":"                ResourceAction::Create | ResourceAction::Update | ResourceAction::Remove\n            )\n        })\n        .unwrap_or(action)\n}\n\nimpl ComposeRequest {\n    #[cfg(test)]\n    fn from_toml(name: String, config: ComposeTomlConfig) -> Result<Self> {\n        Self::from_toml_with_origin(name, config, None)\n    }\n\n    fn from_toml_with_origin(\n        name: String,\n        config: ComposeTomlConfig,\n        origin: Option<ResourceOrigin>,\n    ) -> Result<Self> {\n        if name.is_empty() {\n            bail!(\"bootstrap compose project names cannot be empty\");\n        }\n        if !config.project_dir.is_absolute() {\n            bail!(\n                \"bootstrap compose project '{name}' project_dir must be absolute: {}\",\n                config.project_dir.display()\n            );\n        }\n        validate_project_name(config.project_name.as_deref())?;\n        validate_values(\"profile\", &config.profiles)?;\n        validate_values(\"service\", &config.services)?;\n        validate_values(\"oneshot service\", &config.oneshot)?;\n        validate_command(\"command\", &config.command)?;\n        validate_command(\"engine_command\", &config.engine_command)?;\n        if config.state == ComposeState::Absent && !config.services.is_empty() {\n            bail!(\n                \"bootstrap compose project '{name}' services cannot be combined with state = \\\"absent\\\" because compose down removes the entire project\"\n            );\n        }","sourceCodeStart":297,"sourceCodeEnd":333,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/compose.rs#L297-L333","documentation":"When parsing a bootstrap compose declaration from TOML, the project name key must be a non-empty string. An empty name (e.g. [bootstrap.compose.\"] or name = \"\") cannot identify a compose project, so from_toml_with_origin bails immediately.","triggerScenarios":"A config file contains an empty compose project key under [bootstrap.compose], or programmatic construction passes an empty `name` string to from_toml_with_origin.","commonSituations":"Template/generated config left a placeholder key; a TOML table written as [bootstrap.compose.\"] after an editor mangled it; a script interpolated an unset variable into the section name.","solutions":["Give the compose project a non-empty name in the TOML key","Remove the empty placeholder section if it was left by a template","Check any script that generates the config for an unset/empty variable"],"exampleFix":"# before\n[bootstrap.compose.\"]\nproject_dir = \"/srv/app\"\n\n# after\n[bootstrap.compose.app-db]\nproject_dir = \"/srv/app\"","handlingStrategy":"validation","validationCode":"def validate_compose_names(config: dict) -> None:\n    for name in config.get(\"bootstrap\", {}).get(\"compose\", {}):\n        if not name:\n            raise ValueError(\"bootstrap compose project names cannot be empty\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never generate section headers from unvalidated variables","Lint config TOMLs for empty keys in CI","Use descriptive, stable project names"],"tags":["config","compose","validation"],"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"}