moeru-ai/airi · error
Invalid request body
Error message
Invalid request body
What it means
The MiniMax speech (TTS) provider intercepts the SDK's speech fetch and expects the request body to be a JSON string it can parse. If init.body is missing or not a string, this error is thrown, meaning the TTS request never carried a serializable JSON payload.
Source
Thrown at packages/provider-inference/src/providers/cloud/minimax-speech/index.ts:32
name: 'MiniMax Speech',
nameLocalize: ({ t }) => t('settings.pages.providers.provider.minimax-speech.title'),
description: 'minimax.io',
descriptionLocalize: ({ t }) => t('settings.pages.providers.provider.minimax-speech.description'),
tasks: ['text-to-speech'],
icon: 'i-lobe-icons:minimax',
iconColor: 'i-lobe-icons:minimax-color',
createProviderConfig: () => minimaxSpeechConfigSchema,
createProvider(config) {
const apiKey = config.apiKey.trim()
const baseUrl = (config.baseUrl || 'https://api.minimax.io').replace(/\/$/, '')
return {
speech: () => ({
baseURL: `${baseUrl}/v1/`,
model: 'speech-2.8-hd',
fetch: async (_input: RequestInfo | URL, init?: RequestInit) => {
if (!init?.body || typeof init.body !== 'string')
throw new Error('Invalid request body')
const body = JSON.parse(init.body) as { input?: string, voice?: string, model?: string }
const response = await fetch(`${baseUrl}/v1/t2a_v2`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${apiKey}`,
},
body: JSON.stringify({
model: body.model || 'speech-2.8-hd',
text: body.input ?? '',
stream: true,
voice_setting: {
voice_id: body.voice || 'English_Graceful_Lady',
speed: 1,
vol: 1,
pitch: 0,
},View on GitHub (pinned to f679616c34)
Solutions
- Ensure the TTS request body is a plain JSON string containing at least 'input' (text), 'voice', and 'model'.
- Use the provider through its SDK speech helper instead of hand-rolled fetch calls.
- Remove middleware that converts the body to FormData or streams.
- Pass text via the SDK option (e.g. { input: 'hello' }) so the client serializes JSON.
Example fix
// before
fetch(baseURL, { method: 'POST', body: formData })
// after
fetch(baseURL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ model: 'speech-2.8-hd', input: text, voice })
}) Defensive patterns
Strategy: validation
Validate before calling
const body = JSON.stringify({ model, input: text, voice })
if (typeof body !== 'string' || !text?.trim()) throw new TypeError('TTS request requires JSON string body with non-empty input') Type guard
const isJsonStringBody = (init?: RequestInit): init is RequestInit & { body: string } => typeof init?.body === 'string' Try / catch
try { await tts(text) } catch (e) { if (e.message === 'Invalid request body') { /* send JSON.stringify'd body instead */ } else throw e } Prevention
- Send JSON, never FormData, to the TTS endpoint
- Let the SDK serialize the body
- Don't wrap the provider with body-transforming middleware
- Check Content-Type is application/json
When it happens
Trigger: Calling the speech API with a FormData/Stream/URLSearchParams body instead of JSON, or issuing a GET/empty-body request through the provider's baseURL.
Common situations: Manually calling fetch with multipart form-data; a wrapper that JSON.stringify's into an object rather than a string; using an SDK version that streams the body instead of buffering it into init.body.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Invalid request body
- Invalid speech request body
- Invalid request body
- Invalid request body
- MiMo voice clone requires a base64 audio sample in data URI
AI-assisted analysis of moeru-ai/airi@f679616c34 (2026-09-08).
Data as JSON: /api/errors/c04888f79ab0b714.
Report an issue: GitHub.