jdx/mise · error
unknown workspace project {id:?}
Error message
unknown workspace project {id:?} What it means
WorkspaceProjectGraph::affected_projects() computes the set of changed projects plus every project that transitively depends on them. It fails fast when any passed ProjectId is not a key in the graph's project map. Project IDs are provider-namespaced strings (e.g. "cargo:my-crate", "go:example.com/mod") minted during discovery from Cargo.toml, go.work, package.json, or pyproject.toml, so any ID that was not discovered in the current run is rejected.
Source
Thrown at src/task/workspace.rs:819
pub fn affected_projects<'a>(
&self,
changed: impl IntoIterator<Item = &'a ProjectId>,
) -> Result<BTreeSet<ProjectId>> {
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());
}
}
let mut affected = BTreeSet::new();
let mut pending = Vec::new();
for id in changed {
if !self.projects.contains_key(id) {
bail!("unknown workspace project {id:?}");
}
if affected.insert(id.clone()) {
pending.push(id.clone());
}
}
while let Some(id) = pending.pop() {
for dependent in dependents.get(&id).into_iter().flatten() {
if affected.insert(dependent.clone()) {
pending.push(dependent.clone());
}
}
}
Ok(affected)
}
/// Maps changed paths to affected projects, including workspace-global inputs.
///View on GitHub (pinned to 9dcfcaa0dc)
Solutions
- Verify the ID exists first with graph.get(&id) and log/skip unknown IDs instead of failing
- Re-derive the ID list from the current graph (graph.projects()) rather than reusing IDs captured in a previous session or cache
- Check [monorepo.projects] overrides in mise.toml for a remove = true entry on that ID
- Confirm the owning provider actually discovered the project (member listed in Cargo.toml [workspace].members / go.work use / pnpm workspace globs, not excluded)
Example fix
// before
let affected = graph.affected_projects(["cargo:renamed_crate".parse()?])?;
// after
let id = "cargo:renamed_crate".parse()?;
if graph.get(&id).is_none() {
warn!("project {id} no longer in workspace graph; skipping");
return Ok(Default::default());
}
let affected = graph.affected_projects([id])?; Defensive patterns
Strategy: validation
Validate before calling
let known: Vec<&ProjectId> = requested_ids.iter().filter(|id| graph.get(id).is_some()).collect();
for id in requested_ids.iter().filter(|id| graph.get(id).is_none()) {
warn!("skipping unknown workspace project {id}");
}
let affected = graph.affected_projects(known.iter().copied())?; Type guard
fn is_known_project(graph: &WorkspaceProjectGraph, raw: &str) -> bool {
matches!(raw.parse::<ProjectId>(), Ok(id) if graph.get(&id).is_some())
} Try / catch
match graph.affected_projects(ids) {
Ok(set) => set,
Err(err) if err.to_string().contains("unknown workspace project") => {
warn!("stale project reference: {err}");
Default::default()
}
Err(err) => return Err(err),
} Prevention
- Always source ProjectIds from graph.projects() of the same graph instance you query
- Invalidate cached IDs whenever workspace manifests (Cargo.toml, go.work, package.json) change
- Log graph.provider_discovery_error() before blaming ID inputs — a failed provider shrinks the graph
When it happens
Trigger: Calling graph.affected_projects(ids) with an ID that is not in self.projects: an ID string that was cached or saved from an earlier run (crate/module renamed since), an ID whose project was removed via a [monorepo.projects."<id>"] remove = true override, an ID from a provider that failed lenient discovery (provider_errors retained), or a hand-typed ID with a wrong provider prefix or local part.
Common situations: Stale cached project IDs after renaming a Cargo crate or Go module path; referencing a project that a colleague removed from workspace members; monorepo config drift between branches; a typo like "cargo:my-crate " (whitespace) or "my-crate" (missing provider prefix).
Related errors
- lockfile {:?} attributed to unknown workspace project {id:?}
- workspace provider {:?} attributed lockfile {:?} to foreign
- workspace provider {:?} attributed lockfile {:?} to unknown
- workspace project {:?} depends on unknown project {:?}
- removed workspace project {id:?} cannot define other overrid
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/de61c4a29a041a92.
Report an issue: GitHub.