{"record":{"id":"71e1e13b2cc3c5b6","repo":"jdx/mise","slug":"workspace-provider-provider-id-returned-projec","errorCode":null,"errorMessage":"workspace provider {provider_id:?} returned project ID {:?}; IDs must use the {expected_prefix:?} namespace","messagePattern":"workspace provider (.+?) returned project ID (.+?); IDs must use the (.+?) namespace","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/task/workspace.rs","lineNumber":654,"sourceCode":"        for (provider_id, provider) in providers {\n            let discovered = match provider.discover_with_context(workspace_root, context) {\n                Ok(projects) => projects,\n                Err(error) if skip_provider_errors => {\n                    let error = format!(\"{error:#}\");\n                    warn!(\n                        \"failed to discover {provider_id} workspace projects at {}; inferred tasks \\\n                         and upstream task dependencies from this provider are unavailable: {error}\",\n                        workspace_root.display(),\n                    );\n                    provider_errors.insert(provider_id, error);\n                    continue;\n                }\n                Err(error) => return Err(error),\n            };\n            for mut project in discovered {\n                let expected_prefix = format!(\"{provider_id}:\");\n                let Some(local_id) = project.id.as_str().strip_prefix(&expected_prefix) else {\n                    bail!(\n                        \"workspace provider {provider_id:?} returned project ID {:?}; IDs must use the {expected_prefix:?} namespace\",\n                        project.id\n                    );\n                };\n                validate_id_part(\"project\", local_id)?;\n                project.root = normalize_project_root(&project.id, &project.root)?;\n                attach_provider_provenance(&mut project, &provider_id);\n                let id = project.id.clone();\n                if projects.insert(id.clone(), project).is_some() {\n                    bail!(\n                        \"workspace provider {provider_id:?} returned duplicate project ID {id:?}\"\n                    );\n                }\n            }\n        }\n\n        Ok(Self {\n            projects,","sourceCodeStart":636,"sourceCodeEnd":672,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/task/workspace.rs#L636-L672","documentation":"Each provider must return project IDs already namespaced with its own ID as the prefix (`provider:local`). When a discovered project's ID does not start with `provider_id + \":\"`, the collector bails because cross-provider ID lookups and lockfile attribution depend on this convention.","triggerScenarios":"A provider implementation (in `collect_provider_projects`) returns projects whose `id` field was not formatted as `{provider_id}:{local_id}` — e.g. it set the raw local name or a differently-prefixed ID.","commonSituations":"Writing a custom provider that forgets to prefix IDs; a provider renamed (ID changed) while its project discovery code still builds the old prefix; concatenating the prefix with the wrong separator.","solutions":["Fix the provider to format project IDs as `format!(\"{provider_id}:{local_id}\")`","Ensure the provider's `id()` matches the prefix used when constructing project IDs","Check for a rename: update both the provider ID and the prefix used in project ID generation together"],"exampleFix":"// before\nproject.id = local_id.to_string();\n// after\nproject.id = format!(\"{}:{}\", self.id(), local_id);","handlingStrategy":"try-catch","validationCode":"for project in discovered {\n    assert!(project.id.starts_with(&format!(\"{}:\", provider_id)), \"project {:?} lacks provider prefix\", project.id);\n}","typeGuard":"fn in_namespace(id: &str, provider_id: &str) -> bool { id.starts_with(&format!(\"{provider_id}:\")) }","tryCatchPattern":"match collect_projects(provider) {\n    Ok(ps) => ps,\n    Err(e) if e.to_string().contains(\"namespace\") => {\n        eprintln!(\"provider returned unprefixed project IDs; fix provider id formatting\");\n        return Err(e);\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Centralize project-ID construction in one helper that applies the prefix","Add provider tests asserting returned IDs match the namespace","When renaming a provider, update ID generation and prefix checks together"],"tags":["workspace","provider","namespace"],"backgroundTag":"internal-invariant-violation","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}