{"record":{"id":"a61ad80f1aeebc93","repo":"jdx/mise","slug":"user-service-the-command-contains-c-whi","errorCode":null,"errorMessage":"user service '{}': the command contains {c:?}, which cmd.exe would reinterpret when `environment` is set; move it into a script","messagePattern":"user service '(.+?)': the command contains (.+?), which cmd\\.exe would reinterpret when `environment` is set; move it into a script","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/scheduled_tasks.rs","lineNumber":233,"sourceCode":"        }\n        if let Some(c) = value\n            .chars()\n            .find(|c| matches!(c, '\"' | '%' | '&' | '|' | '<' | '>' | '^' | '\\n' | '\\r'))\n        {\n            bail!(\n                \"user service '{}': environment value for {key} contains {c:?}, which cmd.exe would reinterpret; set it inside the program instead\",\n                request.name\n            );\n        }\n        sets.push(format!(\"set \\\"{key}={value}\\\"\"));\n    }\n    // the command line goes through cmd.exe too: what it would split or\n    // chain is rejected the same way, rather than run differently\n    if let Some(c) = format!(\"{program} {args}\")\n        .chars()\n        .find(|c| matches!(c, '%' | '&' | '|' | '<' | '>' | '^' | '\\n' | '\\r'))\n    {\n        bail!(\n            \"user service '{}': the command contains {c:?}, which cmd.exe would reinterpret when `environment` is set; move it into a script\",\n            request.name\n        );\n    }\n    let program = if program.contains(char::is_whitespace) {\n        format!(\"\\\"{program}\\\"\")\n    } else {\n        program\n    };\n    let rest = if args.is_empty() {\n        program\n    } else {\n        format!(\"{program} {args}\")\n    };\n    Ok((\n        \"cmd.exe\".to_string(),\n        format!(\"/c {} && {rest}\", sets.join(\" && \")),\n    ))","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/scheduled_tasks.rs#L215-L251","documentation":"When `environment` is set, the service command line itself goes through cmd.exe, so characters cmd.exe treats specially (% expansion, &, |, <, >, ^, newlines) would split, chain, or rewrite the command rather than run it literally. exec_action rejects such commands instead of silently changing their meaning.","triggerScenarios":"render_xml -> exec_action on Windows where request.environment is non-empty AND the composed \"{program} {args}\" string contains '%', '&', '|', '<', '>', '^', '\\n', or '\\r'.","commonSituations":"Commands like `foo.exe a & b` or arguments containing '%VAR%' that worked without env injection; multi-line commands pasted into a config; arguments with regex '^' anchors.","solutions":["Move the complex command into a .cmd/.ps1 script and point the service at the script","Remove the special characters or quote/escape them so cmd.exe does not reinterpret them","Avoid setting `environment` if the command only works as a direct (non-cmd) invocation"],"exampleFix":"// before\nprogram: \"app.exe\", args: [\"--flag\", \"a&b\"], environment: {\"X\": \"1\"}\n// after\nprogram: \"C:\\\\scripts\\\\run-app.cmd\" // script handles 'a&b' safely","handlingStrategy":"validation","validationCode":"if (Object.keys(svc.environment).length) {\n  const cmd = [svc.program, ...svc.args].join(' ');\n  const c = [...cmd].find(c => '%&|<>^\\r\\n'.includes(c));\n  if (c) throw new Error(`command contains cmd.exe metacharacter ${c}; use a script`);\n}","typeGuard":"function isCmdSafeCommand(cmd) { return ![...cmd].some(c => '%&|<>^\\r\\n'.includes(c)); }","tryCatchPattern":"try { renderServiceXml(svc); } catch (e) { if (String(e).includes('move it into a script')) { wrapInScript(svc); } else throw e; }","preventionTips":["Whenever environment injection is needed, prefer a wrapper script over a complex inline command","Avoid shell operators in service commands entirely; express chaining inside the script","Test the rendered task with `schtasks /run` in a staging VM before rollout"],"tags":["windows","cmd-exe","escaping","scheduled-tasks"],"backgroundTag":"invalid-argument-value","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}