{"record":{"id":"1540b9a609f075bf","repo":"mastra-ai/mastra","slug":"netlify-gateway-no-token","errorCode":"NETLIFY_GATEWAY_NO_TOKEN","errorMessage":"Missing NETLIFY_TOKEN environment variable required for model: ${routerId}","messagePattern":"Missing NETLIFY_TOKEN environment variable required for model: (.+?)","errorType":"error_code","errorClass":"MastraError","httpStatus":null,"severity":"error","filePath":"packages/core/src/llm/model/gateways/netlify.ts","lineNumber":72,"sourceCode":"      docUrl: 'https://docs.netlify.com/build/ai-gateway/overview/',\n    };\n    // Convert Netlify format to our standard format\n    for (const [providerId, provider] of Object.entries(data.providers)) {\n      for (const model of provider.models) {\n        config.models.push(`${providerId}/${model}`);\n      }\n    }\n    // Return with gateway ID as key - registry generator will detect this and avoid doubling the prefix\n    return { netlify: config };\n  }\n\n  async buildUrl(routerId: string, envVars?: typeof process.env): Promise<string> {\n    // Check for Netlify site ID first (for token exchange)\n    const siteId = envVars?.['NETLIFY_SITE_ID'] || process.env['NETLIFY_SITE_ID'];\n    const netlifyToken = envVars?.['NETLIFY_TOKEN'] || process.env['NETLIFY_TOKEN'];\n\n    if (!netlifyToken) {\n      throw new MastraError({\n        id: 'NETLIFY_GATEWAY_NO_TOKEN',\n        domain: 'LLM',\n        category: 'UNKNOWN',\n        text: `Missing NETLIFY_TOKEN environment variable required for model: ${routerId}`,\n      });\n    }\n\n    if (!siteId) {\n      throw new MastraError({\n        id: 'NETLIFY_GATEWAY_NO_SITE_ID',\n        domain: 'LLM',\n        category: 'UNKNOWN',\n        text: `Missing NETLIFY_SITE_ID environment variable required for model: ${routerId}`,\n      });\n    }\n\n    try {\n      const tokenData = await this.getOrFetchToken(siteId, netlifyToken);","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/llm/model/gateways/netlify.ts#L54-L90","documentation":"NetlifyGateway.buildUrl() exchanges your NETLIFY_SITE_ID + NETLIFY_TOKEN for a short-lived site-scoped AI Gateway token and URL. Before doing so it checks that NETLIFY_TOKEN is present (from the optional envVars argument or process.env). If missing, it throws a MastraError with id NETLIFY_GATEWAY_NO_TOKEN, since the token exchange cannot be authenticated.","triggerScenarios":"Resolving any netlify/<provider>/<model> model (which awaits buildUrl for the gateway base URL) when neither the envVars param nor process.env contains NETLIFY_TOKEN. Also hit by getApiKey, which performs the same check.","commonSituations":"Deploying to serverless/CI where Netlify secrets were never configured; using NETLIFY_AUTH_TOKEN instead of NETLIFY_TOKEN (wrong name); .env not loaded at startup; running locally against Netlify models without a Netlify account token; team members without AI Gateway-enabled sites omitting the variables.","solutions":["Set process.env.NETLIFY_TOKEN to a Netlify personal access token with access to the AI Gateway-enabled site before model resolution.","Also set NETLIFY_SITE_ID — it is required next (a separate NETLIFY_GATEWAY_NO_SITE_ID error follows).","If your token lives under a different name (e.g. NETLIFY_AUTH_TOKEN), copy it: process.env.NETLIFY_TOKEN ??= process.env.NETLIFY_AUTH_TOKEN.","Ensure dotenv/config (or your platform's secret injection) runs before Mastra initializes; verify in serverless that the env vars are attached to the function.","If you don't intend to use Netlify models, avoid netlify/* model ids so the netlify gateway path is never invoked."],"exampleFix":"// before\nconst agent = new Agent({ model: 'netlify/openai/gpt-4o' });\n// after\nimport 'dotenv/config';\nif (!process.env.NETLIFY_TOKEN || !process.env.NETLIFY_SITE_ID) {\n  throw new Error('NETLIFY_TOKEN and NETLIFY_SITE_ID are required for netlify models');\n}\nconst agent = new Agent({ model: 'netlify/openai/gpt-4o' });","handlingStrategy":"validation","validationCode":"import 'dotenv/config';\nif (!process.env.NETLIFY_TOKEN) throw new Error('NETLIFY_TOKEN is required for netlify models');\nif (!process.env.NETLIFY_SITE_ID) throw new Error('NETLIFY_SITE_ID is required for netlify models');","typeGuard":"function hasNetlifyCredentials(env: NodeJS.ProcessEnv = process.env): env is NodeJS.ProcessEnv & { NETLIFY_TOKEN: string; NETLIFY_SITE_ID: string } {\n  return typeof env.NETLIFY_TOKEN === 'string' && env.NETLIFY_TOKEN.length > 0 &&\n         typeof env.NETLIFY_SITE_ID === 'string' && env.NETLIFY_SITE_ID.length > 0;\n}","tryCatchPattern":"import { MastraError } from '@mastra/core';\ntry {\n  const model = mastra.getModel('netlify/openai/gpt-4o');\n} catch (e) {\n  if (e instanceof MastraError && e.id === 'NETLIFY_GATEWAY_NO_TOKEN') {\n    console.error('Set NETLIFY_TOKEN (and NETLIFY_SITE_ID) to use netlify models');\n  }\n  throw e;\n}","preventionTips":["Set both NETLIFY_TOKEN and NETLIFY_SITE_ID in .env and in your deployment's secret store.","Guard against the NETLIFY_AUTH_TOKEN vs NETLIFY_TOKEN naming mismatch.","Load dotenv at the very first import so vars exist before gateway model resolution.","If not using Netlify models, never reference netlify/* model ids so this gateway path stays dormant.","Fail fast at startup with a hasNetlifyCredentials() assert when netlify models are configured."],"tags":["environment","api-key","netlify","configuration","mastra-error"],"backgroundTag":"missing-env-var","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}