HeyPuter/puter · error · HttpError
internal_error
internal_error
Error message
Speech-to-text provider not configured: ${providerName} What it means
The unified STT driver resolved a provider name (explicit, alias, or default) but no provider object was registered under that name in #providers. Providers register on boot regardless of credentials (so their model catalogues stay listable), so this only happens when the resolved name is not one of openai/xai at all — a server-side misconfiguration. Thrown as 500 / internal_error. Distinct from error 410: that fires when the name is unrecognized; this fires when a recognized name was never registered.
Source
Thrown at src/backend/drivers/ai-speech2txt/SpeechToTextDriver.ts:127
async list(): Promise<string[]> {
return Object.keys(this.#providers);
}
async transcribe(args: ITranscribeArgs) {
return this.#provider(args).transcribe(this.#providerArgs(args));
}
async translate(args: ITranscribeArgs) {
return this.#provider(args).translate(this.#providerArgs(args));
}
// -- Provider routing --------------------------------------------
#provider(args: ITranscribeArgs): ISpeechToTextProvider {
const providerName = this.#resolveProvider(args);
const provider = this.#providers[providerName];
if (!provider) {
throw new HttpError(
500,
`Speech-to-text provider not configured: ${providerName}`,
{ 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 !== ''
) {View on GitHub (pinned to 908ec23eda)
Solutions
- Ensure the resolved provider name has a matching registration line in SpeechToTextDriver.#registerProviders.
- Call driver.list() to see which providers are actually configured.
- Let the driver pick the default by not naming a provider.
Example fix
// before: alias resolves 'whisper' -> 'openai' but openai was never registered
// after — in #registerProviders
this.#providers['openai'] = new OpenAISpeechToTextProvider(deps, { apiKey }); Defensive patterns
Strategy: validation
Validate before calling
const configured = await driver.list();
if (!configured.includes(targetProvider)) {
throw new Error(`provider '${targetProvider}' not configured; available: ${configured.join(', ')}`);
} Try / catch
try {
await driver.transcribe(args);
} catch (e) {
if (e?.legacyCode === 'internal_error' && /not configured/.test(e?.message ?? '')) {
// fall back to a provider returned by driver.list()
} else throw e;
} Prevention
- Call driver.list() at app boot and cache the configured set.
- Don't hardcode a provider name that may be disabled per-deployment.
- Keep alias resolution and provider registration in sync when forking.
When it happens
Trigger: A custom fork that added a provider alias in providerAliases.ts without a matching this.#providers[name] = new ... line in #registerProviders; a DEFAULT_SPEECH_TO_TEXT_PROVIDER set to an unregistered id.
Common situations: Fork that extended SPEECH_TO_TEXT_PROVIDERS but forgot the registration branch; a deployment where #registerProviders was overridden and dropped a provider.
Related errors
AI-assisted analysis of HeyPuter/puter@908ec23eda (2026-08-12).
Data as JSON: /api/errors/eb284ab31a9fd49d.
Report an issue: GitHub.