can1357/oh-my-pi · error · AIError.MissingApiKeyError

gitlab-duo-agent

Error message

gitlab-duo-agent

What it means

This MissingApiKeyError is thrown at the top of runGitLabDuoWorkflow when options.apiKey is falsy. The GitLab Duo Workflow provider requires a GitLab access token to call the workflow endpoints, and without one nothing can proceed, so the library fails immediately with the provider name as the message.

Solutions

  1. Set the GitLab token env variable the provider expects (e.g. GITLAB_TOKEN) or pass apiKey explicitly in options
  2. Create a GitLab personal access token with the required api scope if you don't have one
  3. Verify the token isn't an empty string — a failed env lookup can yield "" which is still falsy
  4. Check your config/profile file for a misspelled key name so the credential loader finds it

Example fix

// before
stream({ provider: "gitlab-duo-agent", ... }) // no apiKey
// after
stream({ provider: "gitlab-duo-agent", apiKey: process.env.GITLAB_TOKEN, ... })
Defensive patterns

Strategy: validation

Validate before calling

// Fail fast before calling the provider:
function requireGitlabApiKey(options: { apiKey?: string }): string {
  const key = options.apiKey ?? process.env.GITLAB_TOKEN;
  if (!key) throw new Error("gitlab-duo-agent requires an apiKey (options.apiKey or GITLAB_TOKEN)");
  return key;
}

Type guard

function hasApiKey(o: { apiKey?: string | null }): o is { apiKey: string } {
  return typeof o.apiKey === "string" && o.apiKey.length > 0;
}

Try / catch

try {
  await stream({ provider: "gitlab-duo-agent", ...options });
} catch (err) {
  if (err instanceof AIError.MissingApiKeyError && err.message === "gitlab-duo-agent") {
    console.error("Set GITLAB_TOKEN or pass options.apiKey for gitlab-duo-agent");
    process.exitCode = 1;
  } else throw err;
}

Prevention

When it happens

Trigger: Calling stream with model id 'gitlab-duo-agent' without supplying apiKey in the provider options and without any ambient credential source resolving one — e.g. no GITLAB token in env, no keychain entry, empty string in config.

Common situations: Forgot to set the GitLab personal access token env var; token set under a different variable name than the provider reads; apiKey passed as empty string after a failed env lookup; running in CI where the secret was not injected.

Understand the failure class

Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/0c7a3558999da1fd. Report an issue: GitHub.

Appendix: source

Thrown at packages/ai/src/providers/gitlab-duo-workflow.ts:985

	rootNamespaceId: string;
	restNamespaceId: string;
	createNamespaceId: string;
	restProjectId: string | undefined;
	startPayload: GitLabDuoWorkflowStartRequest;
	webSocketProjectId: string | undefined;
	workflowConnection: GitLabDuoWorkflowDirectAccessConnection;
	workflowId: string;
	selectedModelIdentifier: string;
}

async function runGitLabDuoWorkflow(
	model: Model<"gitlab-duo-agent">,
	context: Context,
	options: GitLabDuoWorkflowOptions,
	state: GitLabDuoWorkflowStreamState,
): Promise<void> {
	const apiKey = options.apiKey;
	if (!apiKey) throw new AIError.MissingApiKeyError("gitlab-duo-agent");
	const baseUrl = normalizeGitLabBaseUrl(model.baseUrl || DEFAULT_GITLAB_BASE_URL);
	const fetchImpl = options.fetch ?? fetch;
	const providerSessionState = getGitLabDuoWorkflowProviderSessionState(
		options.providerSessionState,
		baseUrl,
		model.id,
		options.sessionId,
	);
	state.providerSessionState = providerSessionState;
	const pendingSession = providerSessionState?.active;
	if (pendingSession) {
		hydrateGitLabDuoWorkflowCheckpointState(state, pendingSession);
	}
	const pendingActions = pendingSession?.pendingActions;
	const resolvedBatch =
		pendingSession && pendingActions && pendingActions.length > 0
			? resolveGitLabDuoWorkflowActionBatch(context.messages, pendingActions)
			: undefined;

View on GitHub (pinned to 9690622007)