{"record":{"id":"515c25407f95b02d","repo":"mastra-ai/mastra","slug":"tool-provider-providerid-does-not-support-autho","errorCode":null,"errorMessage":"Tool provider ${providerId} does not support authorize","messagePattern":"Tool provider (.+?) does not support authorize","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"packages/server/src/server/handlers/tool-providers.ts","lineNumber":276,"sourceCode":" * a `tool_provider_connections` row for label / scope joins.\n */\nexport const AUTHORIZE_TOOL_PROVIDER_ROUTE = createRoute({\n  method: 'POST',\n  path: '/tool-providers/:providerId/authorize',\n  responseType: 'json',\n  pathParamSchema: toolProviderIdPathParams,\n  bodySchema: authorizeToolProviderBodySchema,\n  responseSchema: authorizeToolProviderResponseSchema,\n  summary: 'Authorize tool provider connection',\n  description: 'Starts an OAuth flow and returns a redirect URL + opaque auth handle',\n  tags: ['Tool Providers'],\n  requiresAuth: true,\n  handler: async ({ mastra, providerId, toolkit, connectionId, toolName, config, label, scope, requestContext }) => {\n    try {\n      const editor = requireEditor(mastra.getEditor());\n      const provider = await resolveProvider(editor, providerId);\n      if (!provider.authorize) {\n        throw new HTTPException(400, { message: `Tool provider ${providerId} does not support authorize` });\n      }\n      // Per-pin scope:\n      // - 'shared' buckets under SHARED_BUCKET_ID.\n      // - 'caller-supplied' buckets under request-context resourceId (400 if missing).\n      // - 'per-author' (default) buckets under the caller's resolved authorId.\n      //\n      // Precedence: an explicit request `scope` wins, then the provider's\n      // config-level `defaultScope` (the app author's tenancy decision), then\n      // `'per-author'`. This lets a provider constructed with\n      // `defaultScope: 'caller-supplied'` produce per-tenant connections even\n      // though no UI control selects a scope.\n      const requestedScope = scope ?? provider.defaultScope;\n      const effectiveScope: 'shared' | 'per-author' | 'caller-supplied' =\n        requestedScope === 'shared' || requestedScope === 'caller-supplied' ? requestedScope : 'per-author';\n      const callerResourceId = requestContext?.get(MASTRA_RESOURCE_ID_KEY);\n      if (effectiveScope === 'caller-supplied') {\n        if (typeof callerResourceId !== 'string' || callerResourceId.length === 0) {\n          throw new HTTPException(400, {","sourceCodeStart":258,"sourceCodeEnd":294,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/server/src/server/handlers/tool-providers.ts#L258-L294","documentation":"HTTP 400 thrown by the /authorize handler when the resolved provider does not implement the optional authorize method. OAuth-style authorization is opt-in for ToolProviders, so providers without it cannot start connection flows.","triggerScenarios":"POST /api/tool-providers/:providerId/authorize (tool-providers.ts:276) against a provider registered without an authorize implementation.","commonSituations":"Trying OAuth connect on a provider that uses static API keys instead of OAuth; a custom provider implemented before authorize was added to the interface; provider package version too old to support authorization.","solutions":["Implement authorize(...) on the ToolProvider and re-register it.","Use a provider that supports OAuth authorization for interactive connection flows.","Configure credentials statically if the provider only supports non-OAuth auth.","Upgrade the provider package to a version implementing authorize."],"exampleFix":"// before\nclass MyProvider implements ToolProvider { /* no authorize */ }\n// after\nclass MyProvider implements ToolProvider {\n  async authorize({ connectionId, request }) {\n    return { authorizationUrl: this.oauth.buildAuthUrl(connectionId) };\n  }\n}","handlingStrategy":"type-guard","validationCode":"const provider = await api.getProvider(providerId);\nif (typeof provider?.authorize !== 'function') {\n  console.warn(`Provider ${providerId} does not support OAuth authorize`);\n}","typeGuard":"function supportsAuthorize(p: ToolProvider): p is ToolProvider & Required<Pick<ToolProvider, 'authorize'>> {\n  return typeof p.authorize === 'function';\n}","tryCatchPattern":"try {\n  return await api.authorize({ providerId, ... });\n} catch (e) {\n  if (e.status === 400 && /does not support authorize/.test(e.message)) {\n    // fall back to static credential configuration\n  } else throw e;\n}","preventionTips":["Only show 'Connect' buttons for providers that implement authorize.","Prefer static credentials for providers without OAuth support.","Keep custom providers in sync with the current ToolProvider interface."],"tags":["http-400","tool-providers","missing-capability","oauth"],"backgroundTag":"unsupported-provider-capability","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}