jdx/mise · error
lockfile contains multiple optionless resolutions for {short
Error message
lockfile contains multiple optionless resolutions for {short}@{specifier} What it means
During resolution lookup with the legacy (optionless) fallback path, mise expects at most one lockfile entry for short@specifier without request options. If multiple optionless entries match, the resolution is ambiguous and mise bails instead of guessing.
Source
Thrown at src/lockfile.rs:3687
if legacy_options_fallback && !request_options.is_empty() {
let legacy = tools
.iter()
.filter(|tool| tool.specifiers.contains(specifier) && tool.options.is_empty())
.collect_vec();
match legacy.as_slice() {
[] => {}
[found] => {
trace!(
"[{short}@{specifier}] found {} in lockfile without options, keeping the version pin and dropping its artifact data",
found.version
);
return Ok(Some(lockfile_tool_with_request_options(
found,
request_options,
)));
}
_ => bail!(
"lockfile contains multiple optionless resolutions for {short}@{specifier}"
),
}
}
// Mixed-format monorepo migration can temporarily place legacy
// entries without bindings in a version-1 file. Keep those pins
// reachable until a successful full format upgrade binds them.
let version_matches = |v: &LockfileTool| {
v.specifiers.is_empty()
&& lockfile_version_matches(prefix, &v.version)
&& (!require_prefix_boundary
|| lockfile_version_matches_prefix_boundary(prefix, &v.version))
};
let matching = tools
.iter()
.filter(|v| version_matches(v) && &v.options == request_options)
.collect_vec();View on GitHub (pinned to afd2eddd3a)
Solutions
- Deduplicate the [[tools.<short>]] entries in mise.lock so only one optionless entry exists for that specifier
- Regenerate mise.lock from scratch with `mise lock` after backing it up
- Complete the monorepo lockfile migration (run `mise lock --upgrade` at the root) so legacy duplicate entries are collapsed
Example fix
# before (mise.lock) [[tools.node]] version = "20.0.0" [[tools.node]] version = "20.0.0" # after [[tools.node]] version = "20.0.0"
Defensive patterns
Strategy: validation
Validate before calling
// Detect duplicate optionless entries for a tool before lookup
fn optionless_dupes(entries: &[TomlToolEntry]) -> bool {
entries.iter().filter(|e| e.options.is_empty()).count() > 1
} Prevention
- Complete lockfile migrations promptly (`mise lock --upgrade`) so legacy and new entries don't coexist
- Regenerate rather than merge lockfiles manually
- Avoid parallel mise invocations against the same checkout
When it happens
Trigger: Resolving short@specifier against a lockfile where the legacy/optionless matching path finds two or more entries with no options. Caused by duplicated lockfile rows from merges, concurrent lock writes, or hand edits — often seen during mixed-format monorepo migration.
Common situations: Git merge duplicated optionless [[tools.x]] entries; an interrupted `mise lock` left multiple rows; migration between lockfile formats temporarily created both legacy and new entries that collide on lookup.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- lockfile contains multiple resolutions for {short}@{specifie
- unrecognized provenance table format in lockfile: {:?}
- unsupported lockfile format {}
- brew-cask: completion executable '{}' is ambiguous: {}
- No lockfile URL found for {} on platform {} (--locked mode r
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/96732af045bcc3f2.
Report an issue: GitHub.