{"record":{"id":"f6157f948d231604","repo":"can1357/oh-my-pi","slug":"gitlab-duo-workflow-create-failed-with-http-resp","errorCode":null,"errorMessage":"GitLab Duo Workflow create failed with HTTP ${response.status}","messagePattern":"GitLab Duo Workflow create failed with HTTP (.+?)","errorType":"http","errorClass":"AIError.GitLabDuoWorkflowApiError","httpStatus":null,"severity":"error","filePath":"packages/ai/src/providers/gitlab-duo-workflow.ts","lineNumber":1722,"sourceCode":"\t\tworkflowDefinition,\n\t});\n\tconst response = await fetchImpl(gitLabApiUrl(baseUrl, \"/api/v4/ai/duo_workflows/workflows\"), {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\tAuthorization: `Bearer ${apiKey}`,\n\t\t\t\"content-type\": \"application/json\",\n\t\t},\n\t\tbody: JSON.stringify(body),\n\t\tsignal: gitLabDuoWorkflowRestSignal(signal),\n\t});\n\ttraceGitLabDuoWorkflow(\"workflow.create.response\", {\n\t\tstatus: response.status,\n\t\tok: response.ok,\n\t\tnamespaceId,\n\t\thasProjectId: Boolean(projectId),\n\t});\n\tif (!response.ok) {\n\t\tthrow new AIError.GitLabDuoWorkflowApiError(\n\t\t\t`GitLab Duo Workflow create failed with HTTP ${response.status}`,\n\t\t\tresponse.status,\n\t\t);\n\t}\n\tconst payload = (await response.json()) as GitLabCreateWorkflowResponse;\n\tconst workflowId = payload.id ?? payload.workflow_id ?? payload.workflowId;\n\tif (workflowId === undefined) {\n\t\tthrow new AIError.ProviderResponseError(\n\t\t\t`GitLab Duo Workflow create response missing workflow id (HTTP ${response.status})`,\n\t\t\t{ provider: \"gitlab-duo-agent\", kind: \"empty-body\" },\n\t\t);\n\t}\n\ttraceGitLabDuoWorkflow(\"workflow.create.id\", { workflowId });\n\treturn String(workflowId);\n}\n\nasync function stopGitLabDuoWorkflow(\n\tfetchImpl: FetchImpl,","sourceCodeStart":1704,"sourceCodeEnd":1740,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/ai/src/providers/gitlab-duo-workflow.ts#L1704-L1740","documentation":"Thrown when the GitLab Duo Workflow create-workflow POST returns a non-2xx status. The message embeds the HTTP status and the error carries it as errorStatus. This call registers a new workflow with the Duo Workflow service before any streaming begins, so failure aborts the request.","triggerScenarios":"POST create returns 401/403 (bad token or no Duo Workflow access), 404 (namespace/project not found or wrong base URL), 422 (invalid workflow request body), or 5xx — with projectId/namespaceId resolved from the request context.","commonSituations":"Wrong GitLab base URL (self-managed vs gitlab.com); project ID not visible to the token's user; GitLab plan without Duo Workflow; server-side outage.","solutions":["Verify the GitLab token has access to the resolved project/namespace (401/403 → re-auth)","Check the base URL is correct for your instance (404 → wrong host or project path)","For 422, inspect the request the client sent — the model/goal inputs may violate GitLab's constraints","For 5xx, check GitLab status and retry"],"exampleFix":"// before\nbaseUrl: \"https://wrong-gitlab.example.com\"\n// after\nbaseUrl: \"https://gitlab.com\"","handlingStrategy":"try-catch","validationCode":"// Verify project access before creating a workflow:\nconst res = await fetch(`${gitlabBaseUrl}/api/v4/projects/${encodeURIComponent(projectPath)}`, { headers: { authorization: `Bearer ${token}` } });\nif (!res.ok) throw new Error(`Project ${projectPath} not accessible with this token: ${res.status}`);","typeGuard":"function isGitlabDuoApiError(err: unknown): err is InstanceType<typeof AIError.GitLabDuoWorkflowApiError> {\n  return err instanceof AIError.GitLabDuoWorkflowApiError && typeof err.status === \"number\";\n}","tryCatchPattern":"try {\n  const workflowId = await createWorkflow(...);\n} catch (err) {\n  if (err instanceof AIError.GitLabDuoWorkflowApiError && err.status === 404) {\n    throw new Error(\"Wrong GitLab base URL or project path — verify instance and project\");\n  } else if (err instanceof AIError.GitLabDuoWorkflowApiError && err.status >= 500) {\n    // GitLab outage — retry with backoff\n  } else throw err;\n}","preventionTips":["Use the correct base URL per instance (gitlab.com vs self-managed)","Ensure the PAT user can see the target project/namespace","Distinguish 4xx config bugs from 5xx outages in retry logic","Check GitLab service status when 5xx spikes occur"],"tags":["gitlab","http","workflow","api"],"backgroundTag":"http-request-failed","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}