HeyPuter/puter · error · HttpError

bad_request

bad_request

Error message

Speech-to-text provider not found: ${String(args.provider)}. Available: ${SPEECH_TO_TEXT_PROVIDERS.join(', ')}

What it means

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.

Source

Thrown at src/backend/drivers/ai-speech2txt/SpeechToTextDriver.ts:148

                { legacyCode: 'internal_error' },
            );
        }
        return provider;
    }

    /**
     * Decide which provider handles a call: an explicit `provider` wins, then
     * the legacy driver alias the caller dispatched through, then the default.
     */
    #resolveProvider(args: { provider?: unknown }): string {
        if (
            args.provider !== undefined &&
            args.provider !== null &&
            args.provider !== ''
        ) {
            const named = normalizeSpeechToTextProvider(args.provider);
            if (!named) {
                throw new HttpError(
                    400,
                    `Speech-to-text provider not found: ${String(args.provider)}. Available: ${SPEECH_TO_TEXT_PROVIDERS.join(', ')}`,
                    { legacyCode: 'bad_request' },
                );
            }
            return named;
        }

        return (
            normalizeSpeechToTextProvider(Context.get('driverName')) ??
            this.#defaultProvider()
        );
    }

    /** Providers read their own options; `provider` is the driver's business. */
    #providerArgs(args: ITranscribeArgs): ITranscribeArgs {
        const { provider: _provider, ...rest } = args;
        return rest;

View on GitHub (pinned to 908ec23eda)

Solutions

  1. Use a canonical id or alias: openai, whisper, xai, grok, x-ai (case/space tolerant).
  2. Omit provider to use the configured default.

Example fix

// before
driver.transcribe({ file, provider: 'googel' })
// after
driver.transcribe({ file, provider: 'openai' })
Defensive patterns

Strategy: validation

Validate before calling

const STT_ALIASES = ['openai','whisper','grok','x-ai','xai','openai-speech2txt','xai-speech2txt'];
if (args.provider && !STT_ALIASES.includes(String(args.provider).trim().toLowerCase())) {
  throw new Error('unknown speech-to-text provider');
}

Type guard

const isSttProvider = (v: unknown): v is string =>
  typeof v === 'string' &&
  ['openai','whisper','grok','x-ai','xai','openai-speech2txt','xai-speech2txt']
    .includes(v.trim().toLowerCase());

Prevention

When it happens

Trigger: Passing provider: 'azure', provider: 'google', a typo like provider: 'opena', or a non-string value (number/boolean/object).

Common situations: Copy-paste from another AI SDK that uses different provider names; a user-typed provider field; a numeric provider value slipping through unvalidated.

Related errors


AI-assisted analysis of HeyPuter/puter@908ec23eda (2026-08-12). Data as JSON: /api/errors/12b3ba6f18787569. Report an issue: GitHub.