{"record":{"id":"9b51a4d0343cbf55","repo":"jdx/mise","slug":"agent-name-nice-must-be-between-20-and-20","errorCode":null,"errorMessage":"agent '{name}' `nice` must be between -20 and 20","messagePattern":"agent '(.+?)' `nice` must be between -20 and 20","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/launchd.rs","lineNumber":124,"sourceCode":"    pub state: LaunchdState,\n}\n\nimpl LaunchdRequest {\n    pub(crate) fn from_toml(name: String, config: LaunchdTomlConfig) -> Result<Self> {\n        if !valid_name(&name) {\n            bail!(\"agent name '{name}' must contain only letters, numbers, '.', '_', or '-'\");\n        }\n        let Some(program) = config.program.map(|s| s.trim().to_string()) else {\n            bail!(\"agent '{name}' must set `program`\");\n        };\n        if program.is_empty() {\n            bail!(\"agent '{name}' must set a non-empty `program`\");\n        }\n        if config.keep_alive && config.keep_alive_on_failure {\n            bail!(\"agent '{name}' cannot set both `keep_alive` and `keep_alive_on_failure`\");\n        }\n        if config.nice.is_some_and(|nice| !(-20..=20).contains(&nice)) {\n            bail!(\"agent '{name}' `nice` must be between -20 and 20\");\n        }\n        if let Some(interval) = &config.start_calendar_interval {\n            interval.validate(&name)?;\n        }\n        for dir in &config.queue_directories {\n            if dir.trim().is_empty() {\n                bail!(\"agent '{name}' `queue_directories` must not contain empty entries\");\n            }\n            // checked against the raw string rather than `Path::is_absolute` on the\n            // expanded value: the plist is consumed by macOS launchd, so POSIX rules\n            // apply regardless of the platform parsing the config, and on Windows\n            // `Path::new(\"/var/spool\").is_absolute()` is false (root, but no prefix)\n            if !is_absolute_launchd_path(dir) {\n                bail!(\n                    \"agent '{name}' `queue_directories` entry '{dir}' must be an absolute path \\\n                     (launchd requires absolute paths; `~` and `~/` are expanded)\"\n                );\n            }","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/launchd.rs#L106-L142","documentation":"The `nice` value maps to the launchd plist Nice key, which the kernel constrains to the range -20 (highest priority) through 20 (lowest). from_toml validates any provided nice value against this inclusive range and rejects values outside it. This prevents writing a plist launchd or the kernel would refuse.","triggerScenarios":"Setting nice to an integer outside -20..=20 in a [launchd.<name>] section, e.g. nice = 25 or nice = -21.","commonSituations":"Confusing nice with other priority scales (e.g. -100..100); typos like an extra digit; copying an rlimit or ulimit value into the nice field.","solutions":["Set nice to a value within -20..=20 (clamp, e.g. 25 -> 20, -21 -> -20)","Remove the `nice` key if custom priority is not needed","Double-check the intended priority and use 0 (default) or small negative values only if you have permission to raise priority"],"exampleFix":"// before\n[launchd.my-agent]\nnice = 25\n// after\n[launchd.my-agent]\nnice = 20","handlingStrategy":"validation","validationCode":"if let Some(nice) = cfg.get(\"nice\").and_then(|v| v.as_integer()) {\n    if !(-20..=20).contains(&nice) {\n        anyhow::bail!(\"nice must be between -20 and 20, got {nice}\");\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Remember nice is -20..=20, matching the kernel's range","Clamp user-supplied priority values before writing config","Omit `nice` unless priority tuning is actually required"],"tags":["validation","launchd","range"],"backgroundTag":"value-out-of-range","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"}