jdx/mise · error
lockfile attributed to unknown workspace project
Error message
lockfile {:?} attributed to unknown workspace project {id:?} What it means
Lockfile-to-project attribution builds a map of which workspace project IDs each lockfile belongs to; every attributed ID must exist in the workspace. This error fires when a provider (or heuristic) maps a lockfile to a project ID the workspace does not know, so the lockfile cannot be assigned safely.
Solutions
- Delete the orphaned lockfile or restore the project it belonged to
- Re-run workspace discovery so project IDs are current
- Fix the provider's lockfile attribution to only emit IDs from its own discovered project list
Example fix
// before
ids = [format!("{}:{}", self.id(), remembered_name)];
// after
ids = discovered.iter().filter(|p| p.root == lockfile_dir).map(|p| p.id.clone()).collect(); Defensive patterns
Strategy: validation
Validate before calling
for (path, ids) in &lockfile_projects {
for id in ids {
if !workspace.projects.contains_key(id) {
eprintln!("skipping {path:?}: unknown project {id}");
}
}
} Type guard
fn is_known_project<'a>(ws: &Workspace, id: &'a str) -> bool { ws.projects.contains_key(id) } Try / catch
match workspace.attribute_lockfiles(lockfile_projects) {
Ok(p) => p,
Err(e) if e.to_string().contains("attributed to unknown workspace project") => {
eprintln!("stale lockfile or removed project; rediscover and retry");
return Err(e);
}
Err(e) => return Err(e),
} Prevention
- Clean up lockfiles when removing a project directory
- Rediscover projects before lockfile attribution after any config change
- Have providers attribute lockfiles only to projects they themselves discovered
When it happens
Trigger: A provider reports a lockfile whose recorded project ID is absent from the discovered project set — e.g. the project was removed/renamed but its lockfile remains, or the provider invents IDs not matching discovery.
Common situations: Deleted project directory with leftover package-lock.json / Cargo.lock still being scanned; a renamed project where the provider maps the lockfile by old name; config edited between discovery and lockfile scan.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- workspace provider attributed lockfile to unknown project
- pnpm lockfile dependency
- pnpm lockfile dependency
- unknown workspace project
- workspace provider attributed lockfile to foreign project
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/aee15d5858d4a51f.
Report an issue: GitHub.
Appendix: source
Thrown at src/task/workspace.rs:904
.or_default()
.insert(AffectedProjectReason::ChangedPath { path: path.clone() });
}
}
} else {
for id in self.projects.keys() {
projects.entry(id.clone()).or_default().extend(
global_paths
.iter()
.cloned()
.map(|path| AffectedProjectReason::GlobalPath { path }),
);
}
}
for (path, ids) in lockfile_projects {
for id in ids {
if !self.projects.contains_key(id) {
bail!(
"lockfile {:?} attributed to unknown workspace project {id:?}",
path
);
}
projects
.entry(id.clone())
.or_default()
.insert(AffectedProjectReason::Lockfile { path: path.clone() });
}
}
let mut dependents = BTreeMap::<ProjectId, BTreeSet<ProjectId>>::new();
for project in self.projects() {
for dependency in &project.dependencies {
dependents
.entry(dependency.clone())
.or_default()
.insert(project.id.clone());View on GitHub (pinned to 533346cc37)