jdx/mise · error
invalid tool ref {s:?}: must not start with '-'
Error message
invalid tool ref {s:?}: must not start with '-' What it means
validate_ref_string validates `ref:`/`branch:`/`tag:`/`rev:` values with the same rules as version strings; this arm rejects a ref that begins with '-'. Starting with '-' could be misinterpreted as a CLI flag downstream, so mise refuses it during ToolRequest construction.
Source
Thrown at src/toolset/tool_request.rs:649
bail!("invalid tool version {s:?}: contains path-traversal sequence");
}
if let Some(c) = s.chars().find(|c| is_forbidden_version_char(*c)) {
bail!("invalid tool version {s:?}: contains forbidden character {c:?}");
}
Ok(())
}
/// Validate `ref:`/`branch:`/`tag:`/`rev:` values. Same character rules as
/// version strings: branch/tag names already use the same broad vocabulary
/// (`/`, `+`, `-`, etc.), so only shell-quote-breaking characters and leading
/// dashes need rejection. Kept as a separate function for distinct error
/// messages.
fn validate_ref_string(s: &str) -> Result<()> {
if s.is_empty() {
return Ok(());
}
if s.starts_with('-') {
bail!("invalid tool ref {s:?}: must not start with '-'");
}
if s.contains("..") {
bail!("invalid tool ref {s:?}: contains path-traversal sequence");
}
if let Some(c) = s.chars().find(|c| is_forbidden_version_char(*c)) {
bail!("invalid tool ref {s:?}: contains forbidden character {c:?}");
}
Ok(())
}
/// Validate `path:` values. Filesystem paths legitimately contain `/`, spaces,
/// and many other characters, but the resolved path becomes `ctx.rootPath` /
/// `installPath` for path-mode tools and is interpolated into shell commands
/// by some plugin hooks. Reject the same shell-quote-breaking characters as
/// version strings — `$`, backtick, quotes, and `\` — so a hostile `path:`
/// entry in a project config cannot inject shell syntax. Path traversal is
/// intentionally not rejected here because `path:../tools/foo` is a normal
/// relative-path use case.View on GitHub (pinned to afd2eddd3a)
Solutions
- Rename or re-specify the branch/tag without a leading '-', e.g. `ref:feature-x` instead of `ref:-feature-x`.
- If the target genuinely has a leading dash, use `rev:<full-sha>` to pin the commit instead of a name.
- Fix the script/config that generated the ref string and verify with `mise use node@ref:mybranch`.
Example fix
// before (mise.toml)
[tools]
"github:owner/repo" = { ref = "-dev" }
// after
[tools]
"github:owner/repo" = { ref = "dev" } Defensive patterns
Strategy: validation
Validate before calling
function isValidRef(ref) {
return typeof ref === 'string' && (ref === '' || (!ref.startsWith('-') && !ref.includes('..')));
}
if (!isValidRef(ref)) throw new Error(`bad ref: ${ref}`); Type guard
function isSafeRef(v) { return typeof v === 'string' && !v.startsWith('-'); } Prevention
- Never let generated branch/tag names begin with '-' — prefix them if needed.
- Trim and validate output of `git symbolic-ref`/`git describe` before embedding into config.
- Prefer `rev:<sha>` for anything derived from automation.
When it happens
Trigger: A ToolRequest like `git:repo@ref:-weird-branch`, `node@ref:-x`, or a config entry `branch = "-feature"` passed through new_with_options.
Common situations: Branch or tag names that accidentally begin with a dash (often from scripting, e.g. `branch = "$(git symbolic-ref --short HEAD)"` returning an odd value), or typos where the prefix separator got attached to the name.
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
- invalid tool version {s:?}: contains forbidden character {c:
- invalid tool ref {s:?}: contains path-traversal sequence
- invalid tool ref {s:?}: contains forbidden character {c:?}
- brew-cask: invalid {kind} '{value}'
- {option}: '{name}' must be a plain file name (no path separa
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/dd3b3ff74e1221ba.
Report an issue: GitHub.