jdx/mise · error
user service ' ': environment value for contains , which…
Error message
user service '{}': environment value for {key} contains {c:?}, which cmd.exe would reinterpret; set it inside the program instead What it means
Environment VALUES for a user service are injected through `set "key=value"` inside cmd.exe. Characters cmd.exe reinterprets (quotes, percent expansion, chain operators, redirection, escapes, newlines) would change what actually gets set, so exec_action rejects any value containing them.
Solutions
- Remove or escape the offending character from the value
- Set the variable inside the program itself (read from a protected file) instead of via the environment map
- Point the value at a path/config without special characters
Example fix
// before
environment: { "TOKEN": "a%b&c" }
// after
environment: { "TOKEN_FILE": "C:\\secrets\\token.txt" } Defensive patterns
Strategy: validation
Validate before calling
const bad = Object.entries(svc.environment).find(([, v]) => /["%&|<>^\r\n]/.test(v));
if (bad) throw new Error(`env value for ${bad[0]} contains cmd.exe metacharacter`); Type guard
function isCmdSafeValue(v) { return typeof v === 'string' && ![...v].some(c => '"%&|<>^\r\n'.includes(c)); } Try / catch
try { renderServiceXml(svc); } catch (e) { if (String(e).includes('cmd.exe would reinterpret')) { moveSecretsToFile(svc.environment); } else throw e; } Prevention
- Keep secrets and tokens with special characters in files read by the program, not env values
- Strip CRLF when loading env values from Windows text files
- Review env values for % (expansion) and & | < > ^ (operators) before saving
When it happens
Trigger: render_xml -> exec_action on Windows with request.environment containing a value that includes '"', '%', '&', '|', '<', '>', '^', '\n', or '\r'.
Common situations: Passwords or tokens containing '%' or '&' in env values; shell snippets pasted into env values; values with trailing CRLF read from a Windows text file.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- user service ' ': environment key cannot be set through…
- user service ' ': the command contains , which cmd.exe…
- bail!(msg) — dynamic message: uninstalled tool message from…
- brew-cask prune is not supported on windows
- brew import is not supported on windows
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/3aaa7d81d7442147.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/scheduled_tasks.rs:220
/// change are rejected rather than passed through differently.
fn exec_action(request: &ScheduledTaskRequest) -> Result<(String, String)> {
let (program, args) = split_command(&request.command);
if request.environment.is_empty() {
return Ok((program, args));
}
let mut sets = vec![];
for (key, value) in &request.environment {
if key.is_empty() || key.contains(['=', '"', '%', '\n', '\r']) {
bail!(
"user service '{}': environment key {key:?} cannot be set through cmd.exe",
request.name
);
}
if let Some(c) = value
.chars()
.find(|c| matches!(c, '"' | '%' | '&' | '|' | '<' | '>' | '^' | '\n' | '\r'))
{
bail!(
"user service '{}': environment value for {key} contains {c:?}, which cmd.exe would reinterpret; set it inside the program instead",
request.name
);
}
sets.push(format!("set \"{key}={value}\""));
}
// the command line goes through cmd.exe too: what it would split or
// chain is rejected the same way, rather than run differently
if let Some(c) = format!("{program} {args}")
.chars()
.find(|c| matches!(c, '%' | '&' | '|' | '<' | '>' | '^' | '\n' | '\r'))
{
bail!(
"user service '{}': the command contains {c:?}, which cmd.exe would reinterpret when `environment` is set; move it into a script",
request.name
);
}
let program = if program.contains(char::is_whitespace) {View on GitHub (pinned to 533346cc37)