jdx/mise · error
user service '{}': environment key {key:?} cannot be set thr
Error message
user service '{}': environment key {key:?} cannot be set through cmd.exe What it means
On Windows, when a user service request sets environment variables, they are injected by prefixing the command with `set "KEY=VALUE"` executed through cmd.exe. Some characters are illegal or structurally impossible in a cmd.exe environment-variable name, so exec_action rejects them at XML render time rather than emitting a broken service definition.
Source
Thrown at src/system/scheduled_tasks.rs:207
}
out.push_str(" </Exec>\n </Actions>\n");
out.push_str("</Task>\n");
Ok(out)
}
/// Split the command line into the executable and its arguments. Task
/// Scheduler has no environment block, so variables are set through
/// `cmd.exe`, which reinterprets some characters; values that it would
/// 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}")View on GitHub (pinned to afd2eddd3a)
Solutions
- Remove or fix the offending environment key: it must be a non-empty name without '=', '"', '%', or line breaks.
- Strip whitespace/CR-LF from keys when loading environment from files or templates.
- Pass such settings to the program another way (config file, arguments) instead of as a cmd.exe environment variable.
- Validate the environment map before constructing the service request.
Example fix
// before
request.environment.insert("PATH=C:\\bin".into(), "x".into());
// after
request.environment.insert("BIN_DIR".into(), "C:\\bin".into()); Defensive patterns
Strategy: validation
Validate before calling
fn valid_env_key(key: &str) -> Result<(), String> {
if key.is_empty() || key.contains(['=', '"', '%', '\n', '\r']) {
return Err(format!("invalid env key: {key:?}"));
}
Ok(())
} Prevention
- Trim and sanitize keys when loading env maps from files (strip BOM, CRLF, whitespace)
- Never build keys by string concatenation of config fragments
- Reject or log non-conforming keys at config-parse time, not at service-render time
- Prefer simple [A-Za-z_][A-Za-z0-9_]* key names
When it happens
Trigger: Calling render_xml (via exec_action) for a scheduled-task/user-service whose request.environment contains a key that is empty or contains '=', a double quote, '%', a newline, or a carriage return.
Common situations: Copy-pasting env entries with stray whitespace or an embedded '=' from a .env file line; programmatic env maps that include empty-string keys; values loaded from files with CRLF endings where keys picked up a trailing '\r'; templating that interpolates '%' into names.
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:?
- `schtasks {}` failed: {printed}
- scheduled task name {name:?} contains characters that cannot
- querying scheduled task {task} failed: {}
- TEMP is too long to replace mise.exe safely ({len} UTF-16 co
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/42dc2e23554ef579.
Report an issue: GitHub.