can1357/oh-my-pi · error · AIError.MissingApiKeyError
Cursor API key (access token) is required
Error message
Cursor API key (access token) is required
What it means
The Cursor provider authenticates with an API key (Cursor access token) supplied via options.apiKey. streamCursorWithWireMode checks for the key up front and throws MissingApiKeyError when it is absent, before any network traffic. Cursor has no ambient env fallback in this path, so the key must be provided by the caller.
Source
Thrown at packages/ai/src/providers/cursor.ts:681
new AIError.ProviderResponseError("Cursor stream ended before turnEnded", {
kind: "incomplete-stream",
}),
);
return;
}
h2Completion.resolve();
};
// Hoisted out of the try block: the #8345 rotation in the catch path
// needs both ids, and the catch block cannot see try-scoped consts.
let baseConversationId: string | undefined;
let conversationId: string | undefined;
let usageState: UsageState | undefined;
let serializedFallbackWireModelId: string | undefined;
try {
const apiKey = options?.apiKey;
if (!apiKey) {
throw new AIError.MissingApiKeyError(undefined, "Cursor API key (access token) is required");
}
baseConversationId = options?.conversationId ?? options?.sessionId ?? crypto.randomUUID();
conversationId = rotatedConversationIds.get(baseConversationId) ?? baseConversationId;
const rotatedFresh = freshRotatedConversationIds.has(conversationId);
const blobStore = conversationBlobStores.get(conversationId) ?? new Map<string, Uint8Array>();
conversationBlobStores.set(conversationId, blobStore);
const cachedState = rotatedFresh ? undefined : conversationStateCache.get(conversationId);
const builtRequest = await buildGrpcRequestForWireMode(
model,
context,
options,
{
conversationId,
blobStore,
conversationState: cachedState,
rotatedFresh,
},View on GitHub (pinned to 9690622007)
Solutions
- Pass the access token: streamCursor(model, ctx, { apiKey: "<cursor-access-token>" }).
- Generate a new access token from Cursor settings if the old one was revoked, then supply it.
- Load the key from your app's config/credential store and inject it into options before calling.
- Add a startup check that fails fast with a clear message when the Cursor key is missing.
Example fix
// before
await streamCursor(model, context); // no apiKey
// after
await streamCursor(model, context, {
apiKey: process.env.CURSOR_API_KEY,
}); Defensive patterns
Strategy: validation
Validate before calling
const apiKey = options?.apiKey ?? config.cursorAccessToken;
if (!apiKey) throw new Error("Cursor API key (access token) must be supplied via options.apiKey before streaming."); Type guard
null
Try / catch
try {
await streamCursor(model, ctx, options);
} catch (err) {
if (err instanceof AIError.MissingApiKeyError && err.message.includes("Cursor")) {
// prompt for the access token or redirect to credential setup
} else throw err;
} Prevention
- Check for the Cursor access token during app startup.
- Store the token in your credential store and refresh it when rotated.
- Never assume an env fallback exists for this provider — pass the key explicitly.
When it happens
Trigger: Calling streamCursor or the wire-mode streaming path without options.apiKey (or with an empty string), e.g. streaming a cursor/* model with only a model id and context.
Common situations: Cursor access token expired/rotated and removed from config; running in an environment where the credential store isn't populated; forgetting to pass the key after switching from a provider that reads env vars automatically.
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
- Azure OpenAI API key is required. Set AZURE_OPENAI_API_KEY e
- DeepSeek API key is empty after stripping Bearer prefix
- Anthropic Files API credential is required
- No API key for ${model.provider}/${model.id}
- No API key available for model ${model.provider}/${model.id}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/af2c7787bdbc2de8.
Report an issue: GitHub.