{"record":{"id":"dd373b84d78a42b5","repo":"mastra-ai/mastra","slug":"model-not-allowed-by-allowlist","errorCode":null,"errorMessage":"Model not allowed by allowlist","messagePattern":"Model not allowed by allowlist","errorType":"error_code","errorClass":"ModelNotAllowedError","httpStatus":422,"severity":"error","filePath":"packages/core/src/agent-builder/ee/allowlist.ts","lineNumber":106,"sourceCode":"      return {\n        ok: false,\n        attempted: candidate,\n        offendingLabel: candidate.label ?? candidate.origin,\n      };\n    }\n  }\n  return { ok: true };\n}\n\n/**\n * Convenience wrapper around `enforceModelAllowlist` that throws\n * `ModelNotAllowedError` on rejection. Use at write call sites so the server\n * adapter can translate into HTTP 422 + structured body.\n */\nexport function assertModelAllowed(allowed: ProviderModelEntry[] | undefined, input: ModelCandidateInput): void {\n  const result = enforceModelAllowlist(allowed, input);\n  if (result.ok) return;\n  throw new ModelNotAllowedError({\n    allowed,\n    attempted: result.attempted,\n    offendingLabel: result.offendingLabel,\n  });\n}\n","sourceCodeStart":88,"sourceCodeEnd":112,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/agent-builder/ee/allowlist.ts#L88-L112","documentation":"assertModelAllowed validates a model candidate against the agent-builder EE provider allowlist via enforceModelAllowlist. If the candidate is not permitted (not found in the allowlist or matching a denied/offending entry), it throws ModelNotAllowedError, which the server adapter translates to HTTP 422 with a structured body. It enforces that write call sites only accept explicitly allowlisted models.","triggerScenarios":"Calling assertModelAllowed (from an agent-builder write endpoint) with a model id/provider string that is not present in the allowed ProviderModelEntry[] — e.g. requesting 'gpt-5' when the allowlist only contains 'gpt-4o', or an unparseable model string captured as offendingLabel.","commonSituations":"Client UIs sending stale model ids after the allowlist was tightened; new models released but not yet added to the allowlist; typo'd model identifiers; per-workspace allowlists differing from what the client cached.","solutions":["Add the requested model to the ProviderModelEntry allowlist configuration if it should be permitted","Have the client pick models from the server-provided allowlist instead of free-text input","Correct the model id/provider string to match an allowlisted entry exactly","Update cached model lists in the frontend after allowlist changes","Handle HTTP 422 ModelNotAllowedError responses by surfacing allowedModels from the structured body"],"exampleFix":"// before\nassertModelAllowed(allowed, { modelId: 'gpt-5' }); // throws: not allowlisted\n// after\nassertModelAllowed(allowed, { modelId: 'gpt-4o' }); // allowlisted entry","handlingStrategy":"validation","validationCode":"function isAllowlisted(allowed: ProviderModelEntry[] | undefined, modelId: string): boolean {\n  return !!allowed?.some(e => e.modelId === modelId);\n}\nif (!isAllowlisted(allowed, input.modelId)) throw new Error('Model not in allowlist');","typeGuard":"function isAllowedModel(entry: ProviderModelEntry | undefined): entry is ProviderModelEntry {\n  return entry !== undefined;\n}","tryCatchPattern":"try {\n  assertModelAllowed(allowed, candidate);\n} catch (e) {\n  if (e instanceof ModelNotAllowedError) {\n    // return HTTP 422 with e.allowed so the client can pick a valid model\n  }\n}","preventionTips":["Populate client model pickers from the server allowlist, never free text","Re-sync cached model lists after allowlist changes","Add new models to the allowlist at release time","Validate model ids server-side before write endpoints"],"tags":["allowlist","authorization","agent-builder","model-policy"],"backgroundTag":"model-not-allowed-by-allowlist","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}