{"record":{"id":"eb000eee43af4d08","repo":"mastra-ai/mastra","slug":"linear-capabilities-require-an-oauth-connection","errorCode":null,"errorMessage":"Linear capabilities require an OAuth connection.","messagePattern":"Linear capabilities require an OAuth connection\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mastracode/factory/src/integrations/linear/integration.ts","lineNumber":1025,"sourceCode":"  /**\n   * Org-scoped agent tools: issue detail + comment tools for sessions whose\n   * project belongs to an org with an active Linear connection.\n   */\n  async agentTools(args: { requestContext: RequestContext }): Promise<IntegrationTools> {\n    return buildLinearAgentTools({ requestContext: args.requestContext, linear: this });\n  }\n\n  /** Non-secret config snapshot for system diagnostics/startup logs. */\n  diagnostics(): Record<string, unknown> {\n    return {\n      oauthAppConfigured: true,\n    };\n  }\n}\n\nfunction getLinearAccessToken(connection: IntegrationConnection): string {\n  if (connection.type !== 'oauth') {\n    throw new Error('Linear capabilities require an OAuth connection.');\n  }\n  return connection.accessToken;\n}\n\nfunction linearIssueToIntakeIssue(issue: Omit<LinearIssue, 'projectId'>): IntakeIssue {\n  return {\n    id: issue.id,\n    identifier: issue.identifier,\n    title: issue.title,\n    url: issue.url,\n    author: issue.creator,\n    state: issue.state,\n    stateType: issue.stateType,\n    priority: issue.priorityLabel,\n    assignee: issue.assignee,\n    source: issue.team,\n    labels: issue.labels,\n    commentCount: null,","sourceCodeStart":1007,"sourceCodeEnd":1043,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/factory/src/integrations/linear/integration.ts#L1007-L1043","documentation":"`getLinearAccessToken` enforces that a Linear integration connection must be of type `oauth` before any Linear capability runs; non-OAuth connections (e.g. api-key or no connection) carry no usable `accessToken` for the GraphQL API. It is a precondition check guarding all Linear operations that need the token.","triggerScenarios":"Invoking any LinearIntegration capability (fetch/update issues, add comments) with a connection whose `type` is not `'oauth'` — e.g. the integration was configured as a generic API-key connection, the connection record is a placeholder/disconnected stub, or code passed the wrong connection object to the integration.","commonSituations":"Completing the Linear flow with a non-OAuth provider by mistake; storing a Linear API key in a connection record instead of doing the OAuth handshake; a migration/import produced connections with legacy types; tests passing a mock connection without `type: 'oauth'`.","solutions":["Reconnect the Linear integration through the proper OAuth flow so a connection of `type: 'oauth'` with an `accessToken` is stored.","Inspect the stored `IntegrationConnection` and confirm `type === 'oauth'` and `accessToken` is present before invoking Linear capabilities.","If you intended key-based auth, migrate to OAuth — this integration only supports OAuth tokens.","Fix code/tests that construct or pass the wrong connection object to the integration."],"exampleFix":"// before\nuseIntegration('linear', { type: 'api_key', apiKey: process.env.LINEAR_API_KEY })\n// after\nconst conn = await getConnection('linear');\nif (conn?.type !== 'oauth' || !conn.accessToken) {\n  await startOAuthConnect('linear'); // complete the Linear OAuth handshake\n}\nawait useIntegration('linear', conn);","handlingStrategy":"validation","validationCode":"function canUseLinear(conn: IntegrationConnection | undefined): boolean {\n  return !!conn && conn.type === 'oauth' && typeof conn.accessToken === 'string' && conn.accessToken.length > 0;\n}\nif (!canUseLinear(connection)) await startOAuthConnect('linear');","typeGuard":"function isOAuthConnection(c: IntegrationConnection): c is IntegrationConnection & { type: 'oauth'; accessToken: string } {\n  return c.type === 'oauth' && typeof c.accessToken === 'string' && c.accessToken.length > 0;\n}","tryCatchPattern":"try {\n  await integration.runCapability(cap, connection);\n} catch (e) {\n  if (e.message.includes('require an OAuth connection')) {\n    await startOAuthConnect('linear'); // prompt user to (re)connect via OAuth\n    const conn = await getConnection('linear');\n    await integration.runCapability(cap, conn);\n  } else throw e;\n}","preventionTips":["Always create Linear connections through the OAuth flow; don't stuff API keys into connection records.","Check `connection.type === 'oauth'` before invoking any Linear capability.","Guard UI/registration so Linear capabilities are only offered when an OAuth connection exists.","Reconnect when tokens are revoked; treat non-oauth connections as disconnected.","In tests, build fixtures with `type: 'oauth'` and a token."],"tags":["linear","oauth","configuration","auth"],"backgroundTag":"oauth-connection-required","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}