{"record":{"id":"5d886a0f84993d70","repo":"jdx/mise","slug":"user-service-name-name-must-contain-only-lette","errorCode":null,"errorMessage":"user service name '{name}' must contain only letters, numbers, '.', '_', or '-'","messagePattern":"user service name '(.+?)' must contain only letters, numbers, '\\.', '_', or '-'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/user_services.rs","lineNumber":81,"sourceCode":"}\n\nimpl UserServiceRequest {\n    pub(crate) fn from_toml(\n        name: String,\n        config: ServiceTomlConfig,\n        origin: Option<ResourceOrigin>,\n    ) -> Result<Self> {\n        Self::from_toml_with_executable(name, config, origin, durable_mise_executable())\n    }\n\n    fn from_toml_with_executable(\n        name: String,\n        config: ServiceTomlConfig,\n        origin: Option<ResourceOrigin>,\n        executable: Option<PathBuf>,\n    ) -> Result<Self> {\n        if !valid_name(&name) {\n            bail!(\n                \"user service name '{name}' must contain only letters, numbers, '.', '_', or '-'\"\n            );\n        }\n        if config.masked {\n            bail!(\"user service '{name}' cannot be masked; use `state = \\\"absent\\\"` to remove it\");\n        }\n        if config.on_change != super::services_common::ServiceChangeAction::default() {\n            bail!(\"user service '{name}': `on_change` only applies to system services\");\n        }\n        let mut description = config.description;\n        let mut restart = config.restart;\n        let mut nice = None;\n        let mut unresolved = None;\n        let command = match (config.builtin.as_deref(), config.command.as_deref()) {\n            (Some(_), Some(_)) => {\n                bail!(\"user service '{name}' sets both `builtin` and `command`; choose one\")\n            }\n            (None, None) => {","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/user_services.rs#L63-L99","documentation":"User service names are validated in `from_toml_with_executable` with a slightly stricter character set than systemd units (no `@` allowed here): only letters, numbers, `.`, `_`, and `-`. Names failing `valid_name` are rejected before the service definition is registered.","triggerScenarios":"Defining a user service in mise.toml (a `[services]`/user-services TOML block parsed via `from_toml_with_executable`) whose name key contains whitespace, `/`, `:`, `@`, or other special characters.","commonSituations":"Names copied from systemd templated units including `@`; names with spaces like `\"my app\"`; environment suffixes written with `:` (e.g. `api:dev`).","solutions":["Rename the service to use only letters, numbers, `.`, `_`, or `-` (e.g. `my-app-dev`).","Replace `@` templated-style names with a plain hyphenated name.","Remove surrounding whitespace from the TOML key."],"exampleFix":"# before\n[services.\"api:dev\"]\n\n# after\n[services.api-dev]","handlingStrategy":"validation","validationCode":"fn valid_service_name(name: &str) -> bool {\n    !name.is_empty()\n        && name.chars().all(|c| c.is_ascii_alphanumeric() || matches!(c, '.' | '_' | '-'))\n}\nassert!(valid_service_name(\"api-dev\"));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Restrict service names to `[A-Za-z0-9._-]` when generating config from templates.","Avoid `@` and `:` even though systemd allows some of them — this layer is stricter.","Sanitize user/branch names before embedding them in service names."],"tags":["naming","validation","config","services"],"backgroundTag":"invalid-identifier-format","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}