jdx/mise · error
user service '{}': the command contains {c:?}, which cmd.exe
Error message
user service '{}': the command contains {c:?}, which cmd.exe would reinterpret when `environment` is set; move it into a script What it means
When a user service defines environment variables, the whole command line (program + args) is executed through cmd.exe, so characters that cmd treats specially — %, &, |, <, >, ^, and line breaks — would change the meaning of the command. exec_action rejects such command lines up front instead of letting cmd.exe reinterpret them.
Source
Thrown at src/system/scheduled_tasks.rs:229
}
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) {
format!("\"{program}\"")
} else {
program
};
let rest = if args.is_empty() {
program
} else {
format!("{program} {args}")
};
Ok((
"cmd.exe".to_string(),
format!("/c {} && {rest}", sets.join(" && ")),
))View on GitHub (pinned to afd2eddd3a)
Solutions
- Move the redirection/piping/expansion into a wrapper script (.cmd/.ps1) and point the service at that script.
- Remove cmd-specific metacharacters from program/args; perform redirects inside the program (e.g. built-in logging).
- If env vars are not actually needed, unset request.environment so the command no longer runs through cmd.exe.
- Replace '%' expansions with explicit absolute paths.
Example fix
// before
request.environment.insert("MODE".into(), "prod".into());
request.args = ["/c", "app.exe > out.log"].into();
// after
request.program = "C:\\svc\\run.cmd".into(); // script contains the redirect
request.args = [].into(); Defensive patterns
Strategy: validation
Validate before calling
fn cmd_safe_command(program: &str, args: &[String]) -> Result<(), String> {
let line = format!("{program} {}", args.join(" "));
if let Some(c) = line.chars().find(|c| matches!(c, '%' | '&' | '|' | '<' | '>' | '^' | '\n' | '\r')) {
return Err(format!("command contains cmd.exe metachar {c:?}; use a wrapper script"));
}
Ok(())
} Prevention
- Never put redirects, pipes, or %VAR% expansion directly in service commands; wrap in a .cmd/.ps1 script
- Only set request.environment when you actually need it — without env vars the command avoids cmd.exe
- Use absolute paths without spaces or quote paths containing whitespace
- Validate commands at service-definition load time
When it happens
Trigger: Calling render_xml (via exec_action) for a user service that sets request.environment and whose formatted "{program} {args}" string contains '%', '&', '|', '<', '>', '^', '\n', or '\r'. Note this check only runs when environment is set; without env vars the command bypasses cmd.exe.
Common situations: Redirects or pipes written directly into the service command ('app.exe > log.txt'); args containing '&' (URLs, background syntax); '%APPDATA%' style expansion expected in the command; multi-line commands pasted from scripts.
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 value for {key} contains {c:?
- cmd.exe cannot use a UNC path as a working directory work
- TEMP is too long to replace mise.exe safely ({len} UTF-16 co
- Ruby engine '{}' is not supported on Windows. Only standard
- only available on unix
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/a61ad80f1aeebc93.
Report an issue: GitHub.