{"record":{"id":"4a80a30a0a658aa3","repo":"can1357/oh-my-pi","slug":"unhandled-api-in-mapoptionsforapi-model-api","errorCode":null,"errorMessage":"Unhandled API in mapOptionsForApi: ${model.api}","messagePattern":"Unhandled API in mapOptionsForApi: (.+?)","errorType":"exception","errorClass":"AIError.ConfigurationError","httpStatus":null,"severity":"error","filePath":"packages/ai/src/stream.ts","lineNumber":2385,"sourceCode":"\t\tcase \"gitlab-duo-agent\":\n\t\t\treturn castApi<\"gitlab-duo-agent\">({\n\t\t\t\t...base,\n\t\t\t\tcwd: options?.cwd,\n\t\t\t\ttoolChoice: options?.toolChoice,\n\t\t\t});\n\t\tcase \"devin-agent\": {\n\t\t\tconst devinModel = model as Model<\"devin-agent\">;\n\t\t\tconst effort =\n\t\t\t\toptions?.reasoning && !options.disableReasoning\n\t\t\t\t\t? requireSupportedEffort(devinModel, options.reasoning)\n\t\t\t\t\t: undefined;\n\t\t\treturn castApi<\"devin-agent\">({\n\t\t\t\t...base,\n\t\t\t\tchatModelUid: resolveWireModelId(devinModel, effort),\n\t\t\t});\n\t\t}\n\t\tdefault:\n\t\t\tthrow new AIError.ConfigurationError(`Unhandled API in mapOptionsForApi: ${model.api}`);\n\t}\n}\n\nfunction getGoogleBudget(\n\tmodel: Model<\"google-generative-ai\">,\n\teffort: Effort,\n\tcustomBudgets?: ThinkingBudgets,\n): number {\n\trequireSupportedEffort(model, effort);\n\n\t// Custom budgets take precedence if provided for this level\n\tif (customBudgets?.[effort] !== undefined) {\n\t\treturn customBudgets[effort]!;\n\t}\n\n\t// See https://ai.google.dev/gemini-api/docs/thinking#set-budget\n\tconst resolvedBudget = model.thinking?.effortBudgets?.[effort];\n\tif (resolvedBudget !== undefined) return resolvedBudget;","sourceCodeStart":2367,"sourceCodeEnd":2403,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/ai/src/stream.ts#L2367-L2403","documentation":"mapOptionsForApi converts generic request options (e.g. reasoning effort, budgets) into API-specific wire options, but only for APIs it knows. If model.api is not one of the handled cases, it throws AIError.ConfigurationError `Unhandled API in mapOptionsForApi: ${model.api}`. Like the stream dispatch error, it signals the library does not support this API kind — typically a version skew or bad model metadata.","triggerScenarios":"Any streaming/chat call whose model has an api value outside the switch's cases, causing the options-mapping step to hit the default branch.","commonSituations":"Newer/older package versions between pi-ai and the catalog; hand-built Model objects with an unsupported or typo'd api string; third-party registry entries using a custom api name.","solutions":["Upgrade @oh-my-pi/pi-ai so mapOptionsForApi handles the model's api.","Fix the model entry's api field to a supported API kind.","Align package versions (bun install / bun.lock update) so catalog-produced models match supported APIs.","Remove unsupported custom models from the registry."],"exampleFix":"// before\nconst model = { api: \"new-hotness-api\", ... } as Model;\nawait client.chat(model, msgs, { effort: \"high\" });\n// after\nbun update @oh-my-pi/pi-ai @oh-my-pi/pi-catalog\n// or use a supported api:\nconst model = { api: \"anthropic-messages\", ... } as Model<\"anthropic-messages\">;","handlingStrategy":"try-catch","validationCode":"if (!mapOptionsForApiSupports(model.api)) {\n  throw new Error(`Options mapping unsupported for api \"${model.api}\" in this pi-ai version`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await client.chat(model, messages, options);\n} catch (err) {\n  if (err instanceof AIError.ConfigurationError && err.message.includes(\"Unhandled API in mapOptionsForApi\")) {\n    console.error(`api \"${model.api}\" unsupported; upgrade packages or fix the model entry.`);\n    return;\n  }\n  throw err;\n}","preventionTips":["Upgrade pi-ai/catalog together; avoid version skew.","Generate models through the catalog rather than hand-crafting Model objects.","Smoke-test each model/api combination used in production."],"tags":["configuration","unsupported-api","options-mapping","version-mismatch"],"backgroundTag":"unhandled-api-dispatch","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}