jdx/mise · error
user service ' ': environment key cannot be set through…
Error message
user service '{}': environment key {key:?} cannot be set through cmd.exe What it means
When a user service (scheduled task) declares an `environment` map, the values must be injected via a cmd.exe wrapper, and cmd.exe cannot safely set arbitrary environment keys. Keys that are empty or contain '=', quotes, '%', or newlines would break or be reinterpreted by cmd.exe, so exec_action (called by render_xml) rejects them.
Solutions
- Sanitize the environment key: remove '=', quotes, '%' and line breaks
- Set the variable inside the program/script instead of via request.environment
- Wrap the whole env setup in a script file and drop the environment map
Example fix
// before
environment: { "PATH=EXTRA": "/x" }
// after
environment: { "PATH_EXTRA": "/x" } Defensive patterns
Strategy: validation
Validate before calling
const badKey = Object.keys(svc.environment).find(k => !k || /[="%'\r\n]/.test(k));
if (badKey !== undefined) throw new Error(`env key ${JSON.stringify(badKey)} not cmd.exe-safe`); Type guard
function isCmdSafeKey(k) { return typeof k === 'string' && k.length > 0 && !/[="%'\r\n]/.test(k); } Try / catch
try { renderServiceXml(svc); } catch (e) { if (String(e).includes('cannot be set through cmd.exe')) { sanitizeEnvKeys(svc.environment); } else throw e; } Prevention
- Use only [A-Za-z_][A-Za-z0-9_]* for environment keys
- Never build env keys by interpolating raw strings
- Move exotic variables into the program's own config instead of task environment
When it happens
Trigger: Calling the service/task rendering path (render_xml -> exec_action) on Windows for a service whose request.environment contains a key that is empty or contains '=', '"', '%', '\n', or '\r'.
Common situations: Copying Linux-style env definitions with '=' inside keys or quoted keys; keys built by string interpolation that accidentally include a percent sign; multiline keys pasted from a .env 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 value for contains , which…
- user service ' ': the command contains , which cmd.exe…
- querying scheduled task
- scheduled task name contains characters that cannot be…
- `schtasks ` failed
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/42dc2e23554ef579.
Report an issue: GitHub.
Appendix: source
Thrown at src/system/scheduled_tasks.rs:211
}
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 533346cc37)