jdx/mise · error

lockfile {:?} attributed to unknown workspace project {id:?}

Error message

lockfile {:?} attributed to unknown workspace project {id:?}

What it means

affected_projects_for_changes() maps changed paths and provider-attributed lockfiles to affected projects. The lockfile_projects argument is a caller-supplied map from lockfile path to ProjectId set, and every ID in it must exist in the graph. If a lockfile is attributed to a project the graph does not know, mise bail!s with the lockfile path and the offending ID.

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 9dcfcaa0dc)

Solutions

  1. Recompute attribution at query time with graph.affected_projects_for_lockfile(providers, path, before, after) instead of reusing a stale map
  2. Filter the map's IDs through graph.get() and drop (or re-resolve) unknown ones before calling affected_projects_for_changes
  3. Invalidate stored lockfile attributions whenever workspace member manifests (Cargo.toml, go.work, package.json, pyproject.toml) change

Example fix

// before
let affected = graph.affected_projects_for_changes(root, paths, &[], &stale_lockfile_map)?;

// after
let lockfile_map: BTreeMap<_, _> = stale_lockfile_map
    .into_iter()
    .map(|(path, ids)| {
        (path, ids.into_iter().filter(|id| graph.get(id).is_some()).collect())
    })
    .collect();
let affected = graph.affected_projects_for_changes(root, paths, &[], &lockfile_map)?;
Defensive patterns

Strategy: validation

Validate before calling

let lockfile_projects: BTreeMap<PathBuf, BTreeSet<ProjectId>> = raw_map
    .into_iter()
    .map(|(path, ids)| (path, ids.into_iter().filter(|id| graph.get(id).is_some()).collect()))
    .collect();
let affected = graph.affected_projects_for_changes(root, paths, global_inputs, &lockfile_projects)?;

Type guard

fn lockfile_map_is_current(graph: &WorkspaceProjectGraph, map: &BTreeMap<PathBuf, BTreeSet<ProjectId>>) -> bool {
    map.values().flatten().all(|id| graph.get(id).is_some())
}

Try / catch

match graph.affected_projects_for_changes(root, paths, gi, &map) {
    Ok(res) => res,
    Err(err) if err.to_string().contains("attributed to unknown workspace project") => {
        graph.affected_projects_for_changes(root, paths, gi, &BTreeMap::new())? // rebuild without stale attribution
    }
    Err(err) => return Err(err),
}

Prevention

When it happens

Trigger: Passing a lockfile_projects map whose IDs came from an earlier graph build (workspace membership changed since: crate renamed, module dropped from go.work, project removed via override), or from a different workspace root/provider set than the graph being queried.

Common situations: Monorepo tooling that caches 'which lockfile affects which project' across runs; reattributing lockfiles after pulling a branch that restructured packages; CI replaying an old attribution map against a fresh checkout.

Related errors


AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17). Data as JSON: /api/errors/aee15d5858d4a51f. Report an issue: GitHub.