{"record":{"id":"8093fcb9691811b2","repo":"jdx/mise","slug":"bootstrap-compose-project-name-oneshot-service","errorCode":null,"errorMessage":"bootstrap compose project '{name}' oneshot services must also appear in services","messagePattern":"bootstrap compose project '(.+?)' oneshot services must also appear in services","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/compose.rs","lineNumber":360,"sourceCode":"        {\n            bail!(\n                \"bootstrap compose project '{name}' down_volumes and down_images require state = \\\"absent\\\"\"\n            );\n        }\n        if config.state != ComposeState::Running && config.renew_anonymous_volumes {\n            bail!(\n                \"bootstrap compose project '{name}' renew_anonymous_volumes requires state = \\\"running\\\"\"\n            );\n        }\n        let explicit_dependencies = config\n            .depends_on\n            .iter()\n            .map(|dependency| parse_dependency(dependency))\n            .collect::<Result<Vec<_>>>()?;\n        let services = dedupe(config.services);\n        let oneshot: IndexSet<String> = dedupe(config.oneshot).into_iter().collect();\n        if !services.is_empty() && oneshot.iter().any(|service| !services.contains(service)) {\n            bail!(\n                \"bootstrap compose project '{name}' oneshot services must also appear in services\"\n            );\n        }\n        let files = resolve_paths(&config.project_dir, config.files);\n        let env_files = resolve_paths(&config.project_dir, config.env_files);\n        let path_dependencies = std::iter::once(ResourceId::new(\n            \"directory\",\n            config.project_dir.to_string_lossy(),\n        ))\n        .chain(\n            files\n                .iter()\n                .chain(&env_files)\n                .map(|path| ResourceId::new(\"file\", path.to_string_lossy())),\n        )\n        .collect::<IndexSet<_>>()\n        .into_iter()\n        .collect();","sourceCodeStart":342,"sourceCodeEnd":378,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/compose.rs#L342-L378","documentation":"Thrown during TOML validation when the `oneshot` list names services that are not present in the project's `services` list. Oneshot services are started and shut down around a task run, so they must be members of the project's service set; the library rejects dangling ones.","triggerScenarios":"A `[system.compose.<name>]` block with a non-empty `services` list where at least one entry of `oneshot` does not appear in `services`. Raised from `from_toml_with_origin` at parse time. Note: only checked when `services` is non-empty.","commonSituations":"Typo in a oneshot service name; adding a one-shot helper container to `oneshot` but forgetting to also list it under `services`; renaming a service in one list but not the other.","solutions":["Add the missing service names to the `services` list","Fix the spelling of the oneshot entries so they match `services`"],"exampleFix":"# before\n[system.compose.myproj]\nservices = [\"db\", \"api\"]\noneshot = [\"migrate\"]\n# after\n[system.compose.myproj]\nservices = [\"db\", \"api\", \"migrate\"]\noneshot = [\"migrate\"]","handlingStrategy":"validation","validationCode":"let missing: Vec<_> = cfg.oneshot.iter()\n    .filter(|s| !cfg.services.contains(s))\n    .collect();\nassert!(missing.is_empty(), \"oneshot not in services: {missing:?}\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat services as the source of truth; derive oneshot from it","Grep-check that oneshot names match service definitions","Keep compose service names and mise config in sync via tests"],"tags":["config","validation","docker-compose"],"backgroundTag":"invalid-argument-value","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"}