{"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":"exception","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/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/task/workspace.rs#L636-L672","documentation":"Each workspace provider must namespace every discovered project's ID as `<provider_id>:<local_id>`. When a provider returns a project whose ID does not begin with its own `provider_id:` prefix, mise rejects the workspace so project IDs stay globally unambiguous and attributable to their provider.","triggerScenarios":"A workspace provider's `discover`-style API returns a WorkspaceProject whose `id` string does not start with `format!(\"{provider_id}:\")`; also fires for a provider whose local project ID part would be empty or malformed.","commonSituations":"Custom or third-party provider implementations returning bare IDs like `\"api\"` instead of `\"monorepo:api\"`; renaming a provider in config while its projects still carry the old prefix; hand-written provider plugins that skip the namespacing convention.","solutions":["Fix the provider so it prefixes every project ID with its own provider ID, e.g. `\"monorepo:api\"` for provider id \"monorepo\".","If the provider ID was renamed, update the provider's returned project IDs to the new prefix.","Validate the local ID part also passes identifier validation (no invalid characters) after the prefix."],"exampleFix":"// before (provider discovery output)\nWorkspaceProject { id: \"api\", root: \"services/api\", .. }\n\n// after\nWorkspaceProject { id: \"monorepo:api\", root: \"services/api\", .. }","handlingStrategy":"validation","validationCode":"fn assert_namespaced(provider_id: &str, projects: &[WorkspaceProject]) -> Result<(), String> {\n    projects.iter()\n        .find(|p| !p.id.starts_with(&format!(\"{provider_id}:\")))\n        .map_or(Ok(()), |p| Err(format!(\"project id {} lacks prefix {provider_id}:\", p.id)))\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Build project IDs centrally in provider code via a helper that always applies the namespace prefix.","Test custom providers with a unit test asserting every returned ID starts with the provider prefix.","When renaming a provider ID, search and update all returned project IDs."],"tags":["workspace","provider","naming","validation"],"backgroundTag":"invalid-identifier-format","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}