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

  1. Pass an engine from VALID_ENGINES: 'standard', 'neural', 'long-form', or 'generative'.
  2. Omit engine to list voices across all engines.
  3. 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

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.