moeru-ai/airi · error

Failed to fetch voices: ${response.statusText}

Error message

Failed to fetch voices: ${response.statusText}

What it means

The index-tts-vllm provider's listVoices fetches the voice list from the local vLLM server. If the server responds with a non-ok HTTP status, this error is thrown with the statusText. It indicates the configured IndexTTS vLLM endpoint rejected or failed the request.

Source

Thrown at packages/provider-inference/src/providers/local/index-tts-vllm/index.ts:81

          return { errors: [], reason: '', reasonKey: '', valid: true }
        },
      }),
    ],
  },
  extraMethods: {
    listModels: async () => [{
      id: 'IndexTTS-1.5',
      name: 'IndexTTS-1.5',
      provider: 'index-tts-vllm',
      description: 'Default model for Index-TTS vLLM deployment',
      contextLength: 0,
      deprecated: false,
    }],
    listVoices: async (config) => {
      const response = await fetch(voicesUrl(config))
      if (!response.ok)
        throw new Error(`Failed to fetch voices: ${response.statusText}`)

      const voices = await response.json() as Record<string, unknown>
      return Object.keys(voices).map(voice => ({
        id: voice,
        name: voice,
        provider: 'index-tts-vllm',
        languages: [{ code: 'cn', title: 'Chinese' }, { code: 'en', title: 'English' }],
      }))
    },
  },
})

View on GitHub (pinned to f679616c34)

Solutions

  1. Check the vLLM server is running and healthy (curl the voices endpoint directly).
  2. Verify the configured baseUrl/points to the correct host and port.
  3. Wait for model loading to finish and retry; add retry/backoff for 503 during startup.
  4. Inspect vLLM server logs for the corresponding 5xx cause.
  5. Check proxy/firewall rules if the service runs in another container/host.

Example fix

// before
baseUrl: 'http://localhost:8001' // wrong port
// after
baseUrl: 'http://localhost:8000' // actual vLLM server port
Defensive patterns

Strategy: retry

Validate before calling

const health = await fetch(voicesUrl).then(r => r.ok)
if (!health) throw new Error('IndexTTS vLLM endpoint unreachable before listing voices')

Try / catch

try { voices = await provider.listVoices(config) } catch (e) {
  if (/Failed to fetch voices/.test(e.message)) await retryWithBackoff(() => provider.listVoices(config))
  else throw e
}

Prevention

When it happens

Trigger: The vLLM server returns 404 (wrong path/port), 500 (model not loaded), 503 (server starting), or the request hits a wrong service/proxy returning an error status.

Common situations: IndexTTS vLLM service not fully started yet; incorrect baseUrl/port in config; server crashed or model still loading; a reverse proxy in front returning 404/502; firewall or wrong host in a container setup.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of moeru-ai/airi@f679616c34 (2026-09-08). Data as JSON: /api/errors/ca9b904a3e65660f. Report an issue: GitHub.