{"record":{"id":"40b086e57ff3f393","repo":"jdx/mise","slug":"cannot-write-windows-launcher-because-is-not-a-40b086","errorCode":null,"errorMessage":"cannot write Windows launcher because {} is not a generated launcher","messagePattern":"cannot write Windows launcher because (.+?) is not a generated launcher","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/generate/tool_stub.rs","lineNumber":222,"sourceCode":"        Ok(())\n    }\n\n    /// Refuse to replace a `.cmd` beside the stub that mise did not write.\n    ///\n    /// `--output` is the user's choice, so `<stub>.cmd` is a name a project may already be using\n    /// for a script of its own, and nothing about that name says mise owns it. The stub itself is\n    /// different: the user named it, so overwriting it is what they asked for.\n    fn validate_windows_launcher(&self, stub_content: &str) -> Result<()> {\n        if !wants_windows_launcher(stub_content) {\n            return Ok(());\n        }\n        let Some(launcher) = super::windows_launcher_path(&self.output) else {\n            return Ok(());\n        };\n        match fs::symlink_metadata(&launcher) {\n            Ok(metadata) if metadata.file_type().is_file() => {\n                if !super::is_generated_launcher(&file::read_to_string(&launcher)?) {\n                    bail!(\n                        \"cannot write Windows launcher because {} is not a generated launcher\",\n                        display_path(&launcher)\n                    );\n                }\n            }\n            Ok(_) => bail!(\n                \"cannot write Windows launcher because {} is not a regular file\",\n                display_path(&launcher)\n            ),\n            Err(err) if matches!(err.kind(), ErrorKind::NotFound | ErrorKind::NotADirectory) => {}\n            Err(err) => return Err(err.into()),\n        }\n        Ok(())\n    }\n\n    fn get_tool_name(&self) -> String {\n        self.output\n            .file_name()","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/jdx/mise/blob/9dcfcaa0dc8747a2577d3270b69bb9d8313b2807/src/cli/generate/tool_stub.rs#L204-L240","documentation":"`mise generate tool-stub --output <file>` writes a `<file>.cmd` launcher beside the shebang stub so Windows can run it (CreateProcess will not execute shebang scripts). That launcher path already holds a regular file that is not a mise-generated launcher (must be `@echo off` + `rem generated by mise` + one line ending in ` %*`). Since nothing about the name says mise owns it, mise refuses to overwrite it; validation runs before the stub is written so the run fails without partial output.","triggerScenarios":"`mise generate tool-stub --output bin/mytool --url ...` when bin/mytool.cmd is a project-authored batch script, or an old launcher that was edited beyond recognition.","commonSituations":"Repo already ships bin/<name>.cmd wrappers; Windows CI scripts sharing the stub's base name; stub regenerated after someone customized the .cmd.","solutions":["If the .cmd is hand-written, rename it (`git mv bin/mytool.cmd bin/mytool-run.cmd`) or relocate its logic","If it is a stale generated launcher you no longer want, delete it and rerun","Choose an `--output` name whose `.cmd` sibling is free"],"exampleFix":"# before\n$ mise generate tool-stub --output bin/kubectl --url https://...\n# error: bin/kubectl.cmd is not a generated launcher\n\n# after\n$ git mv bin/kubectl.cmd scripts/kubectl.cmd\n$ mise generate tool-stub --output bin/kubectl --url https://...","handlingStrategy":"type-guard","validationCode":"#!/bin/bash\nOUT=bin/mytool\nif [ -e \"$OUT.cmd\" ] && [ -f \"$OUT.cmd\" ]; then\n  is_mise_launcher \"$OUT.cmd\" || { echo \"$OUT.cmd is hand-written — rename it first\" >&2; exit 1; }\nfi\nmise generate tool-stub --output \"$OUT\" --url \"$URL\"","typeGuard":"is_mise_launcher() {\n  [ \"$(head -1 \"$1\")\" = '@echo off' ] && [ \"$(sed -n 2p \"$1\")\" = 'rem generated by mise' ] && [ \"$(tail -1 \"$1\")\" = \"$(tail -1 \"$1\" | sed 's/.* //')\" ]\n}","tryCatchPattern":"if ! mise generate tool-stub --output bin/mytool --url \"$URL\"; then\n  [ -f bin/mytool.cmd ] && echo 'bin/mytool.cmd is not generated — rename or remove it, then rerun' >&2\n  exit 1\nfi","preventionTips":["Choose stub output names whose .cmd sibling is unused by project scripts","Never hand-edit generated .cmd launchers — mise stops recognizing them","Keep Windows wrappers in a separate directory (scripts/) from tool stubs"],"tags":["mise","tool-stub","windows","cmd-launcher","ownership","generate"],"backgroundTag":"generated-file-ownership-conflict","analyzedSha":"9dcfcaa0dc8747a2577d3270b69bb9d8313b2807","analyzedAt":"2026-08-17T14:28:50.624Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}