Custom flow fails to authenticate against GitLab API
<!--IssueSummary start--> <details> <summary> Everyone can contribute. [Help move this issue forward](https://handbook.gitlab.com/handbook/marketing/developer-relations/contributor-success/community-contributors-workflows/#contributor-links) while earning points, leveling up and collecting rewards. </summary> - [Close this issue](https://contributors.gitlab.com/manage-issue?action=close&projectId=278964&issueIid=594248) </details> <!--IssueSummary end--> ### Summary <!-- Summarize the bug encountered concisely. --> ### Steps to reproduce I defined a custom flow to pull git submodules before running an MR Review. It's a 2 steps flow, with 1. DeterministicStepComponent to pull git submodule, 2. AgentComponent to actually run the MR Review When the flow starts, it installs `duo cli`, then tests SRT sandbox and starts defining its settings with `srt --settings /tmp/srt-settings.json duo run --existing-session-id 3197378 --connection-type websocket`. This logs an error (without failing the job/pipeline) but fails the agent session without additional information. Job logs: ``` 2026-03-20T09:11:42:945 [error]: Error: Fetching version from https://gitlab.com/api/v4/version failed. The request requires higher privileges than provided by the access token. at G91 (file:///usr/lib/node_modules/@gitlab/lib_core/src/fetch/handle_fetch_error.ts:10:11) at processTicksAndRejections (node:internal/process/task_queues:95:5) at wc.fetchFromApi (file:///usr/lib/node_modules/@gitlab/lib_core/src/gitlab_api/simple_api_client.ts:88:5) at ry.#J (file:///usr/lib/node_modules/@gitlab/lib_core/src/feature_flags/instance_feature_flags.ts:229:27) at ry.#G (file:///usr/lib/node_modules/@gitlab/lib_core/src/feature_flags/instance_feature_flags.ts:247:19) at Object.<anonymous> (file:///usr/lib/node_modules/@gitlab/lib_core/src/feature_flags/instance_feature_flags.ts:98:7) - Error details: - REST Request: - Method: GET - Path: /api/v4/version - Response: - Status: 403 - Headers: {"cache-control":"no-cache","cf-cache-status":"MISS","cf-ray":"9df3974ce9efdd6f-ATL","connection":"close","content-encoding":"gzip","content-security-policy":"default-src 'none'","content-type":"application/json","date":"Fri, 20 Mar 2026 09:11:42 GMT","gitlab-lb":"haproxy-main-33-lb-gprd","gitlab-sv":"gke-cny-api","nel":"{\"max_age\": 0}","referrer-policy":"strict-origin-when-cross-origin","server":"cloudflare","set-cookie":"_cfuvid=d3P9XQzRNi2hhw2vIzOzG4zihaDhAE1WrSDPFBbqF0E-1773997902927-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None","strict-transport-security":"max-age=31536000","transfer-encoding":"chunked","vary":"Origin, Accept-Encoding","x-content-type-options":"nosniff","x-gitlab-meta":"{\"correlation_id\":\"9df3974ce9efdd6f-ATL\",\"version\":\"1\"}","x-request-id":"9df3974ce9efdd6f-ATL","x-runtime":"0.026915"} - Response body: {"error":"insufficient_scope","error_description":"The request requires higher privileges than provided by the access token.","scope":"read_user ai_features api read_api"} [...] 2026-03-20T09:11:43:428 [debug]: [DuoWorkflowNodeExecutor][3197378] websocket connection created successfully 2026-03-20T09:11:43:428 [info]: [MCP] Sandbox mode detected (GITLAB_WORKFLOW_SANDBOX=true) - skipping external MCP servers 2026-03-20T09:11:43:428 [info]: [DuoWorkflowNodeExecutor][3197378] startRequest: mcp_tools=0 preapproved_tools=0 servers=0 2026-03-20T09:11:43:428 [debug]: [DuoWorkflowNodeExecutor][3197378] startRequest: approved_tools=[] 2026-03-20T09:11:43:428 [debug]: [DuoWorkflowNodeExecutor][3197378] Writing startRequest to stream with CLIENT_CAPABILITIES: shell_command... 2026-03-20T09:11:43:431 [debug]: [DuoWorkflowNodeExecutor][3197378] startRequest write returned: true 2026-03-20T09:11:43:431 [debug]: [DuoWorkflowNodeExecutor][3197378] startRequest written to stream 2026-03-20T09:11:43:431 [debug]: [DuoWorkflowNodeExecutor][3197378] Entering event queue iteration... 2026-03-20T09:11:44:116 [debug]: [WebSocketWorkflowClient] WebSocket connection closed: {"code":1000,"reason":""} 2026-03-20T09:11:44:116 [debug]: [WebSocketWorkflowClient] Heartbeat stopped 2026-03-20T09:11:44:117 [debug]: [DuoWorkflowNodeExecutor][3197378] Stream end event received 2026-03-20T09:11:44:117 [debug]: [DuoWorkflowNodeExecutor][3197378] Event queue iteration completed 2026-03-20T09:11:44:117 [debug]: [PreConfiguredWorkflowTokenService] Ignoring revoke request for workflow "3197378" - pre-configured tokens cannot be revoked 2026-03-20T09:11:44:117 [info]: [GitLabBackend] Workflow completed successfully 2026-03-20T09:11:44:128 [info]: [CliExitHandler] Shutting down gracefully... 2026-03-20T09:11:44:129 [debug]: [PreConfiguredWorkflowTokenService] Disposed pre-configured token service 2026-03-20T09:11:44:129 [info]: [ExecutorManager] Disposing ExecutorManager (1 active executors) 2026-03-20T09:11:44:130 [debug]: [ExecutorManager] Disposing executor for workflow "3197378". 2026-03-20T09:11:44:130 [info]: [DuoWorkflowNodeExecutor][3197378] Disposing executor - starting shutdown 2026-03-20T09:11:44:130 [info]: [DuoWorkflowNodeExecutor][3197378] Force disconnecting - aborting any outstanding action handlers, ending stream 2026-03-20T09:11:44:131 [info]: [MCP Manager] Disposing service 2026-03-20T09:11:44:131 [info]: [DuoWorkflowNodeExecutor][3197378] Force disconnected 2026-03-20T09:11:44:132 [info]: [CliExitHandler] Shutdown complete, good bye :) $ else $ else $ echo "Command execution completed with exit code: $?" Command execution completed with exit code: 0 Cleaning up project directory and file based variables 00:00 Job succeeded ``` Session details: ``` Session information AI Item: Ai catalog agent Session ID: #3197378 Type: Flow Project: nodejs-sample-gcp Group: gcp Triggered by: @odupre Status: Failed Started: 20 Mar 2026, 09:54 Last updated: 20 Mar 2026, 10:11 Job ID: #13575593850 ``` ### Example Project This happens on my project: https://gitlab.com/gl-demo-ultimate-odupre/gcp/nodejs-sample-gcp. I can grant you access if needed. Here is the flow definition: ``` version: "v1" environment: ambient components: # 1. Deterministic step to init submodules - name: "git_submodules_init" type: DeterministicStepComponent tool_name: "run_git_command" inputs: - from: "git submodule update --init --recursive" as: "command" literal: true # 2. Your MR review agent - name: "custom_mr_review_agent" type: AgentComponent prompt_id: "custom_mr_review_prompt" inputs: - "context:goal" toolset: - "read_file" - "read_files" - "list_dir" - "build_review_merge_request_context" - "post_duo_code_review" - "get_merge_request" - "list_merge_request_diffs" - "list_all_merge_request_notes" - "create_merge_request_note" ui_log_events: - "on_agent_final_answer" - "on_tool_execution_success" prompts: - prompt_id: "custom_mr_review_prompt" name: "Custom MR Review" unit_primitives: [] prompt_template: system: | You are GitLab Duo Chat, an agentic AI assistant. Your role is to help users with their GitLab tasks. Be concise, accurate, and actionable in your responses. You are an experienced software engineer. Review the MR and provide clear, actionable feedback. user: | {{goal}} params: timeout: 360 routers: - from: "git_submodules_init" to: "custom_mr_review_agent" - from: "custom_mr_review_agent" to: "end" flow: entry_point: "git_submodules_init" ``` ### What is the current *bug* behavior? The job succeeds despite an error in its logs. The Agent session fails without clear and explicit explanation and without delivering expected results. ### What is the expected *correct* behavior? * The job does not fail (access to GitLab API is authorized) * The 2 steps of the Flow succeeds. ### Output of checks <!-- If you are reporting a bug on GitLab.com, uncomment below --> This bug happens on GitLab.com <!-- and uncomment below if you have /label privileges -->
issue