{"record":{"id":"12b3ba6f18787569","repo":"HeyPuter/puter","slug":"bad-request-12b3ba","errorCode":"bad_request","errorMessage":"Speech-to-text provider not found: ${String(args.provider)}. Available: ${SPEECH_TO_TEXT_PROVIDERS.join(', ')}","messagePattern":"Speech-to-text provider not found: (.+?)\\. Available: (.+?)","errorType":"validation","errorClass":"HttpError","httpStatus":400,"severity":"error","filePath":"src/backend/drivers/ai-speech2txt/SpeechToTextDriver.ts","lineNumber":148,"sourceCode":"                { legacyCode: 'internal_error' },\n            );\n        }\n        return provider;\n    }\n\n    /**\n     * Decide which provider handles a call: an explicit `provider` wins, then\n     * the legacy driver alias the caller dispatched through, then the default.\n     */\n    #resolveProvider(args: { provider?: unknown }): string {\n        if (\n            args.provider !== undefined &&\n            args.provider !== null &&\n            args.provider !== ''\n        ) {\n            const named = normalizeSpeechToTextProvider(args.provider);\n            if (!named) {\n                throw new HttpError(\n                    400,\n                    `Speech-to-text provider not found: ${String(args.provider)}. Available: ${SPEECH_TO_TEXT_PROVIDERS.join(', ')}`,\n                    { legacyCode: 'bad_request' },\n                );\n            }\n            return named;\n        }\n\n        return (\n            normalizeSpeechToTextProvider(Context.get('driverName')) ??\n            this.#defaultProvider()\n        );\n    }\n\n    /** Providers read their own options; `provider` is the driver's business. */\n    #providerArgs(args: ITranscribeArgs): ITranscribeArgs {\n        const { provider: _provider, ...rest } = args;\n        return rest;","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/HeyPuter/puter/blob/908ec23eda38526170322c3edf71ba45ecb1ca95/src/backend/drivers/ai-speech2txt/SpeechToTextDriver.ts#L130-L166","documentation":"The caller passed an explicit, non-empty provider that normalizeSpeechToTextProvider could not map through the alias table (openai, whisper, grok, x-ai, xai, and their *-speech2txt forms). Thrown as 400 / bad_request with the full allowlist in the message. The value is trimmed and lowercased before lookup, so case/whitespace is tolerated but typos and unknown names are not.","triggerScenarios":"Passing provider: 'azure', provider: 'google', a typo like provider: 'opena', or a non-string value (number/boolean/object).","commonSituations":"Copy-paste from another AI SDK that uses different provider names; a user-typed provider field; a numeric provider value slipping through unvalidated.","solutions":["Use a canonical id or alias: openai, whisper, xai, grok, x-ai (case/space tolerant).","Omit provider to use the configured default."],"exampleFix":"// before\ndriver.transcribe({ file, provider: 'googel' })\n// after\ndriver.transcribe({ file, provider: 'openai' })","handlingStrategy":"validation","validationCode":"const STT_ALIASES = ['openai','whisper','grok','x-ai','xai','openai-speech2txt','xai-speech2txt'];\nif (args.provider && !STT_ALIASES.includes(String(args.provider).trim().toLowerCase())) {\n  throw new Error('unknown speech-to-text provider');\n}","typeGuard":"const isSttProvider = (v: unknown): v is string =>\n  typeof v === 'string' &&\n  ['openai','whisper','grok','x-ai','xai','openai-speech2txt','xai-speech2txt']\n    .includes(v.trim().toLowerCase());","tryCatchPattern":null,"preventionTips":["Drive the provider picker from driver.list_models({ provider: 'all' }).","Normalize and trim provider input before sending.","Reject non-string provider values client-side."],"tags":["validation","provider-routing","speech2txt"],"backgroundTag":null,"analyzedSha":"908ec23eda38526170322c3edf71ba45ecb1ca95","analyzedAt":"2026-08-12T20:53:15.911Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}