{"record":{"id":"7d7500178a2137dc","repo":"jdx/mise","slug":"pnpm-lockfile-dependency-name-has-no-resolvabl","errorCode":null,"errorMessage":"pnpm lockfile dependency {name:?} has no resolvable version","messagePattern":"pnpm lockfile dependency (.+?) has no resolvable version","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/task/workspace/node.rs","lineNumber":397,"sourceCode":"    }\n    Ok(reachable)\n}\n\nfn dependency_package_keys(node: &Value, available: &BTreeSet<String>) -> Result<Vec<String>> {\n    let mut packages = Vec::new();\n    for field in [\"dependencies\", \"devDependencies\", \"optionalDependencies\"] {\n        let Some(dependencies) = node.get(field).and_then(Value::as_mapping) else {\n            continue;\n        };\n        for (name, value) in dependencies {\n            let Some(name) = name.as_str() else {\n                continue;\n            };\n            let version = value\n                .as_str()\n                .or_else(|| value.get(\"version\").and_then(Value::as_str));\n            let Some(version) = version else {\n                eyre::bail!(\"pnpm lockfile dependency {name:?} has no resolvable version\");\n            };\n            packages.extend(resolve_package_keys(name, version, available)?);\n        }\n    }\n    Ok(packages)\n}\n\nfn resolve_package_keys(\n    name: &str,\n    version: &str,\n    available: &BTreeSet<String>,\n) -> Result<Vec<String>> {\n    if [\"link:\", \"workspace:\", \"file:\"]\n        .iter()\n        .any(|prefix| version.starts_with(prefix))\n    {\n        return Ok(Vec::new());\n    }","sourceCodeStart":379,"sourceCodeEnd":415,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/task/workspace/node.rs#L379-L415","documentation":"While walking a pnpm lockfile to derive task workspace package keys (dependency_package_keys), mise reads each dependency entry and extracts its version either from a plain string value or from a `version` key in the dependency object. When neither yields a string, the dependency has no version that can be resolved against the lockfile's package snapshots, so mise aborts rather than silently mis-mapping the dependency graph.","triggerScenarios":"Calling reachable_packages over a pnpm-lock.yaml where a dependency entry is neither a version string nor an object containing a string `version` field — e.g. a lockfile v9 entry with only a specifier, a `link:`/`file:` dependency with no version, or a hand-edited/corrupted lockfile.","commonSituations":"Hand-edited pnpm lockfiles; pnpm workspaces using `link:` workspace protocol deps whose entries carry only a resolution/specifier; lockfiles produced by a much newer pnpm than the parser anticipates; merge conflicts resolved incorrectly in pnpm-lock.yaml.","solutions":["Regenerate pnpm-lock.yaml with `pnpm install` so every dependency entry carries a resolvable version","Inspect the lockfile entry for the named dependency and remove or fix malformed entries (merge leftovers, link:/file: deps without versions)","Check your pnpm version and lockfileVersion compatibility; commit a lockfile format the current mise supports"],"exampleFix":"// before (pnpm-lock.yaml, malformed entry)\ndependencies:\n  left-pad:\n    specifier: ^1.0.0\n\n// after\ndependencies:\n  left-pad:\n    specifier: ^1.0.0\n    version: 1.3.0","handlingStrategy":"validation","validationCode":"// before trusting a pnpm lockfile entry\nconst version = typeof dep === 'string' ? dep : (typeof dep === 'object' && typeof dep.version === 'string' ? dep.version : null);\nif (!version) throw new Error(`dependency ${name} has no resolvable version; run pnpm install`);","typeGuard":"function hasVersion(d) { return typeof d === 'string' || (d !== null && typeof d === 'object' && typeof d.version === 'string'); }","tryCatchPattern":null,"preventionTips":["Never hand-edit pnpm-lock.yaml; let pnpm regenerate it","Keep pnpm updated in step with the lockfileVersion you commit","Resolve merge conflicts in lockfiles by regenerating, not by hand"],"tags":["pnpm","lockfile","node","parsing"],"backgroundTag":"schema-validation-failed","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}