HeyPuter/puter · error · HttpError

field_required

field_required

Error message

Missing required field: text

What it means

ElevenLabsTTSProvider.synthesize requires a non-empty text string. If text is not a string or trims to empty (and test_mode is off), it throws HTTP 400 (legacyCode field_required) with fields.key='text', before voice/model resolution and credit checks.

Source

Thrown at src/backend/drivers/ai-tts/providers/elevenlabs/ElevenLabsTTSProvider.ts:211

        args: ISynthesizeArgs,
    ): Promise<DriverStreamResult | { url: string; content_type: string }> {
        const {
            text,
            voice: voiceArg,
            model: modelArg,
            response_format,
            output_format,
            voice_settings,
            voiceSettings,
            test_mode,
        } = args;

        if (test_mode) {
            return { url: SAMPLE_AUDIO_URL, content_type: 'audio' };
        }

        if (typeof text !== 'string' || !text.trim()) {
            throw new HttpError(400, 'Missing required field: text', {
                legacyCode: 'field_required',
                fields: { key: 'text' },
            });
        }

        const voiceId = voiceArg || this.defaultVoiceId;
        const modelId = modelArg || DEFAULT_MODEL;

        // Gate on the cost table rather than the advertised model list: an id
        // we can't price is an id we can't bill for, and the vendor bills us
        // for it either way.
        if (!Object.hasOwn(ELEVENLABS_TTS_COSTS, modelId)) {
            const expected = Object.keys(ELEVENLABS_TTS_COSTS);
            throw new HttpError(
                400,
                `Invalid model: ${modelId}. Expected: ${expected.join(', ')}`,
                {
                    legacyCode: 'field_invalid',

View on GitHub (pinned to 908ec23eda)

Solutions

  1. Pass a non-empty text string.
  2. Trim and validate text on the client before calling.
  3. Use test_mode: true during integration to bypass for connectivity checks.

Example fix

// before
await driver.synthesize({ provider: 'elevenlabs', voice: '21m00Tcm4TlvDq8ikWAM' });
// after
await driver.synthesize({ text: 'Hello world', provider: 'elevenlabs', voice: '21m00Tcm4TlvDq8ikWAM' });
Defensive patterns

Strategy: validation

Validate before calling

function synthesizeElevenLabs(text, opts = {}) {
  if (typeof text !== 'string' || !text.trim()) {
    throw new Error('text is required and must be a non-empty string');
  }
  return driver.synthesize({ text, provider: 'elevenlabs', ...opts });
}

Type guard

const isNonEmptyString = (v: unknown): v is string =>
  typeof v === 'string' && v.trim().length > 0;

if (isNonEmptyString(text)) {
  await driver.synthesize({ text, provider: 'elevenlabs' });
}

Prevention

When it happens

Trigger: Calling synthesize on the elevenlabs provider with text omitted, null, empty, whitespace-only, or a non-string type.

Common situations: Form submission with empty input; passing prompt text into the wrong field; whitespace-only content; migrating from another provider and forgetting the text argument name.

Related errors


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