{"record":{"id":"fa9028fb71b25ada","repo":"jdx/mise","slug":"managed-path-notifies-unconfigured-bootstrap","errorCode":null,"errorMessage":"managed path '{}' notifies unconfigured bootstrap service '{}'","messagePattern":"managed path '(.+?)' notifies unconfigured bootstrap service '(.+?)'","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/services.rs","lineNumber":503,"sourceCode":"        .iter()\n        .map(|service| service.name.as_str())\n        .collect::<IndexSet<_>>();\n    for (resource, notification) in files\n        .iter()\n        .flat_map(|file| {\n            file.notify\n                .iter()\n                .map(move |notification| (file.path.as_path(), notification))\n        })\n        .chain(directories.iter().flat_map(|directory| {\n            directory\n                .notify\n                .iter()\n                .map(move |notification| (directory.path.as_path(), notification))\n        }))\n    {\n        if !configured.contains(notification.as_str()) {\n            bail!(\n                \"managed path '{}' notifies unconfigured bootstrap service '{}'\",\n                resource.display(),\n                notification\n            );\n        }\n    }\n    Ok(())\n}\n\npub(crate) fn plans_with_notifications(\n    requests: &[ServiceRequest],\n    notifications: &ServiceNotifications,\n) -> Vec<ResourcePlan> {\n    requests\n        .iter()\n        .map(|request| request.plan_with_change(notifications.change_for(request)))\n        .collect()\n}","sourceCodeStart":485,"sourceCodeEnd":521,"githubUrl":"https://github.com/jdx/mise/blob/6f52dcdf99e282ef7a7db68c81301fa4618d0f79/src/system/services.rs#L485-L521","documentation":"mise validates that every `notify` entry on a managed path (`[[bootstrap.files]]` or `[[bootstrap.directories]]`) names a service actually declared under `[bootstrap.services]`. A notify on an undeclared service would have nothing to signal at apply time, so configuration loading fails with this error.","triggerScenarios":"A `[[bootstrap.files]]` or `[[bootstrap.directories]]` block contains `notify = [\"name\"]` where `name` is not a key in any `[bootstrap.services.*]` table of the loaded config (typo, renamed service, or the services block was deleted/moved to an untracked file).","commonSituations":"Renaming a service but forgetting the notify references; copying a bootstrap file block from another project without its services block; notify names the unit filename (`foo.service`) while the services table key is the bare name or vice versa.","solutions":["Add the matching `[bootstrap.services.<name>]` table for the notify target","Fix the typo in the notify array so it matches an existing service key exactly","Remove the notify entry if no reload/restart is needed on changes to that path"],"exampleFix":"# before\n[[bootstrap.files]]\npath = \"/etc/myapp/config.yaml\"\nnotify = [\"myap\"]\n\n# after\n[[bootstrap.files]]\npath = \"/etc/myapp/config.yaml\"\nnotify = [\"myapp\"]\n\n[bootstrap.services.myapp]\nstate = \"running\"\non_change = \"restart\"","handlingStrategy":"validation","validationCode":"jq -r '[.bootstrap.services // {} | keys[]] as $s | (.bootstrap.files // []) + (.bootstrap.directories // []) | .notify[]? | select(. as $n | $s | index($n) | not) | \"dangling notify: \\(.)\"' mise.toml","typeGuard":null,"tryCatchPattern":null,"preventionTips":["When renaming a service, grep the whole config for its old name (notify arrays included)","Add a CI lint that cross-checks every notify target against the services keys","Prefer few, centralized notify references over scattered ones"],"tags":["mise","bootstrap","config","notify","validation"],"backgroundTag":"unresolved-config-reference","analyzedSha":"6f52dcdf99e282ef7a7db68c81301fa4618d0f79","analyzedAt":"2026-08-22T10:14:23.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}