HeyPuter/puter · error · HttpError
invalid_engine
invalid_engine
Error message
Invalid engine: ${engine}. Valid engines: ${VALID_ENGINES.join(', ')} What it means
AWSPollyTTSProvider.listVoices filters Polly's voice catalogue by engine. If args.engine is supplied and is not one of VALID_ENGINES ('standard','neural','long-form','generative'), it throws HTTP 400 (legacyCode invalid_engine), echoing the valid set and attaching fields.engine and fields.valid_engines.
Source
Thrown at src/backend/drivers/ai-tts/providers/awsPolly/AWSPollyTTSProvider.ts:176
v.SupportedEngines?.includes(engine),
);
return fallback ? fallback.Id : 'Salli';
}
async listVoices(args?: Record<string, unknown>): Promise<ITTSVoice[]> {
const engine = args?.engine as string | undefined;
const pollyVoices = await this.describeVoices();
let voices = pollyVoices.Voices;
if (engine) {
if (VALID_ENGINES.includes(engine)) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
voices = voices.filter((voice: any) =>
voice.SupportedEngines?.includes(engine),
);
} else {
throw new HttpError(
400,
`Invalid engine: ${engine}. Valid engines: ${VALID_ENGINES.join(', ')}`,
{
legacyCode: 'invalid_engine',
fields: { engine, valid_engines: VALID_ENGINES },
},
);
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return voices.map((voice: any) => ({
id: voice.Id,
name: voice.Name,
language: {
name: voice.LanguageName,
code: voice.LanguageCode,
},View on GitHub (pinned to 908ec23eda)
Solutions
- Pass an engine from VALID_ENGINES: 'standard', 'neural', 'long-form', or 'generative'.
- Omit engine to list voices across all engines.
- Call list_engines({ provider: 'aws-polly' }) to fetch the valid engine ids dynamically.
Example fix
// before
await driver.list_voices({ provider: 'aws-polly', engine: 'neuronal' });
// after
await driver.list_voices({ provider: 'aws-polly', engine: 'neural' }); Defensive patterns
Strategy: validation
Validate before calling
const VALID_ENGINES = ['standard', 'neural', 'long-form', 'generative'];
function listPollyVoices(engine) {
if (engine !== undefined && !VALID_ENGINES.includes(engine)) {
throw new Error(`engine must be one of ${VALID_ENGINES.join(', ')}`);
}
return driver.list_voices({ provider: 'aws-polly', engine });
} Type guard
const VALID_ENGINES = ['standard', 'neural', 'long-form', 'generative'] as const; type PollyEngine = typeof VALID_ENGINES[number]; const isPollyEngine = (v: unknown): v is PollyEngine => typeof v === 'string' && (VALID_ENGINES as readonly string[]).includes(v);
Prevention
- Prefer fetching engines via list_engines({ provider: 'aws-polly' }) over hardcoding.
- When engine is optional, leave it undefined to list voices across all engines.
- Validate with a shared constant to keep client and server in sync.
When it happens
Trigger: Calling list_voices({ provider: 'aws-polly', engine: 'neuronal' }) or any engine string outside VALID_ENGINES. The check runs only when engine is truthy; omitting it returns all voices.
Common situations: Typos ('neuronal', 'standard1'); using an AWS Polly engine name that doesn't exist; copy-pasting an engine id from another provider into the Polly voice listing.
Related errors
AI-assisted analysis of HeyPuter/puter@908ec23eda (2026-08-12).
Data as JSON: /api/errors/e4fe5853cbfeb3f3.
Report an issue: GitHub.