{"record":{"id":"b425294625d7ab9d","repo":"can1357/oh-my-pi","slug":"unable-to-find-a-gitlab-duo-workflow-namespace-wit","errorCode":null,"errorMessage":"Unable to find a GitLab Duo Workflow namespace with available models. Set GITLAB_DUO_NAMESPACE_ID to a root namespace with Duo model access.","messagePattern":"Unable to find a GitLab Duo Workflow namespace with available models\\. Set GITLAB_DUO_NAMESPACE_ID to a root namespace with Duo model access\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/catalog/src/discovery/gitlab-duo-workflow.ts","lineNumber":215,"sourceCode":"export function buildGitLabDuoWorkflowFallbackModel(\n\tid = FALLBACK_MODEL_ID,\n\tname = FALLBACK_MODEL_NAME,\n\tbaseUrl = GITLAB_DEFAULT_BASE_URL,\n): ModelSpec<\"gitlab-duo-agent\"> {\n\treturn buildGitLabDuoWorkflowModelSpec({ name, ref: id }, baseUrl);\n}\n\nasync function selectGitLabDuoWorkflowNamespace(\n\tconfig: GitLabDuoWorkflowDiscoveryConfig,\n): Promise<GitLabDuoWorkflowNamespaceSelectionWithModels> {\n\tconst baseUrl = normalizeGitLabBaseUrl(config.baseUrl);\n\tconst selection = await selectGitLabDuoWorkflowCandidate(config, baseUrl, candidate =>\n\t\tvalidateNamespaceCandidate(config, baseUrl, candidate),\n\t);\n\tif (selection) {\n\t\treturn selection;\n\t}\n\tthrow new Error(\n\t\t\"Unable to find a GitLab Duo Workflow namespace with available models. Set GITLAB_DUO_NAMESPACE_ID to a root namespace with Duo model access.\",\n\t);\n}\n\ntype GitLabDuoWorkflowCandidateResolver<TSelection> = (\n\tcandidate: GitLabDuoWorkflowCandidate,\n) => Promise<TSelection | null> | TSelection | null;\n\nasync function selectGitLabDuoWorkflowCandidate<TSelection>(\n\tconfig: GitLabDuoWorkflowDiscoveryConfig,\n\tbaseUrl: string,\n\tresolveCandidate: GitLabDuoWorkflowCandidateResolver<TSelection>,\n\tenrichNamespaceOverride = false,\n): Promise<TSelection | null> {\n\tconst namespaceId = normalizeIdentifier(config.namespaceId) ?? normalizeIdentifier(Bun.env.GITLAB_DUO_NAMESPACE_ID);\n\tif (namespaceId) {\n\t\tconst candidate = enrichNamespaceOverride\n\t\t\t? ((await fetchNamespaceOverrideCandidate(config, baseUrl, namespaceId)) ?? {","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/catalog/src/discovery/gitlab-duo-workflow.ts#L197-L233","documentation":"Thrown by selectGitLabDuoWorkflowNamespace when every candidate namespace was rejected by validateNamespaceCandidate — i.e. namespaces were found, but none offers available Duo Workflow models. Unlike the runtime-namespace error, configuration was resolvable but yielded no usable models.","triggerScenarios":"selectGitLabDuoWorkflowNamespace/selection where each candidate namespace fails model validation (empty model list, no Duo access on the namespace, or API returning models the validator filters out).","commonSituations":"Namespace lacks a Duo Workflow subscription/seat; GITLAB_DUO_NAMESPACE_ID points to a subgroup (not root) without model access; self-managed instance without duo features licensed; token scopes fine but the account isn't a Duo beta/entitled member.","solutions":["Point GITLAB_DUO_NAMESPACE_ID at a root namespace whose plan includes Duo model access.","Confirm in the GitLab UI that Duo Chat/Workflow models are listed for that namespace.","Check the token belongs to a user with Developer+ access in that namespace and Duo enabled."],"exampleFix":"// before: subgroup without Duo models\nGITLAB_DUO_NAMESPACE_ID=my-group/sub-team\n// after: root namespace with Duo access\nGITLAB_DUO_NAMESPACE_ID=my-group","handlingStrategy":"try-catch","validationCode":"null","typeGuard":"null","tryCatchPattern":"try {\n  const sel = await selectGitLabDuoWorkflowNamespace(config);\n} catch (err) {\n  if (err.message.includes(\"namespace with available models\")) {\n    // namespace resolved but has no Duo models — check plan/licensing\n    logger.error(\"GitLab namespace has no Duo models\", { namespace: process.env.GITLAB_DUO_NAMESPACE_ID });\n  }\n  throw err;\n}","preventionTips":["Verify the namespace's plan includes Duo model access before wiring discovery.","Use a root namespace with an active Duo subscription/seat.","Spot-check GET /api/v4/... model endpoints with the same token before integrating."],"tags":["gitlab","discovery","configuration","permissions"],"backgroundTag":"gitlab-namespace-no-models","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}