HeyPuter/puter · error · HttpError

field_required

field_required

Error message

Missing required field: text

What it means

GeminiTTSProvider.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 model/voice resolution and cost checks.

Source

Thrown at src/backend/drivers/ai-tts/providers/gemini/GeminiTTSProvider.ts:146

    }

    async synthesize(
        args: ISynthesizeArgs,
    ): Promise<DriverStreamResult | { url: string; content_type: string }> {
        const {
            text,
            voice: voiceArg,
            model: modelArg,
            instructions,
            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 model = modelArg || DEFAULT_MODEL;
        if (!GEMINI_TTS_MODELS.find(({ id }) => id === model)) {
            throw new HttpError(
                400,
                `Invalid model: ${model}. Expected: ${GEMINI_TTS_MODELS.map(({ id }) => id).join(', ')}`,
                {
                    legacyCode: 'field_invalid',
                    fields: {
                        key: 'model',
                        expected: GEMINI_TTS_MODELS.map(({ id }) => id).join(
                            ', ',
                        ),
                        got: model,

View on GitHub (pinned to 908ec23eda)

Solutions

  1. Pass a non-empty text string.
  2. Trim and validate text client-side before the call.
  3. Use test_mode: true to validate connectivity without text.

Example fix

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

Strategy: validation

Validate before calling

function synthesizeGemini(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: 'gemini', ...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: 'gemini' });
}

Prevention

When it happens

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

Common situations: Empty prompt submission; passing instructions but leaving text blank; whitespace-only input; type mismatch from a loosely typed caller.

Related errors


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