n8n-io/n8n · error · NodeOperationError
No audio data returned
Error message
No audio data returned
What it means
Thrown when the /t2a_v2 response has a successful status_code (0) but response.data.audio is missing or empty. This is a response-shape inconsistency: MiniMax signalled success yet did not return the synthesized audio payload the node expects.
Source
Thrown at packages/@n8n/nodes-langchain/nodes/vendors/MiniMax/actions/audio/tts.operation.ts:242
if (options.languageBoost) {
body.language_boost = options.languageBoost;
}
const response = (await apiRequest.call(this, 'POST', '/t2a_v2', {
body,
})) as T2AResponse;
if (response.base_resp?.status_code !== 0) {
throw new NodeOperationError(
this.getNode(),
`Text-to-speech failed: ${response.base_resp?.status_msg || 'Unknown error'}`,
);
}
const audioData = response.data?.audio;
if (!audioData) {
throw new NodeOperationError(this.getNode(), 'No audio data returned');
}
const jsonData: IDataObject = {
audioLength: response.extra_info?.audio_length,
audioFormat: response.extra_info?.audio_format,
audioSize: response.extra_info?.audio_size,
wordCount: response.extra_info?.word_count,
usageCharacters: response.extra_info?.usage_characters,
};
if (downloadAudio) {
const audioResponse = await this.helpers.httpRequest({
method: 'GET',
url: audioData,
encoding: 'arraybuffer',
returnFullResponse: true,
});
View on GitHub (pinned to 5ac6606e81)
Solutions
- Retry the identical request — most occurrences are transient.
- Log the full response body to confirm whether data.audio is truly absent vs. moved.
- Verify the base URL in credentials points at the official MiniMax endpoint (https://api.minimax.io/v1) and not a filtering proxy.
- Shorten input text and retry to rule out a partial-failure edge case.
Defensive patterns
Strategy: retry
Validate before calling
// There is no caller-side input that prevents an upstream success-with-no-audio glitch.
// The only meaningful pre-check is to confirm the request shape matches the API contract.
function validateTtsRequestShape(body: IDataObject): string | null {
if (typeof body.text !== 'string' || body.text.length === 0) return 'body.text must be a non-empty string';
if (typeof body.voice_setting !== 'object' || body.voice_setting === null) return 'body.voice_setting is required';
return null;
} Type guard
function hasAudioPayload(r: unknown): r is { data: { audio: string } } {
return typeof (r as { data?: { audio?: unknown } })?.data?.audio === 'string' &&
((r as { data: { audio: string } }).data.audio.length > 0);
} Try / catch
async function ttsWithRetry(apiRequest: any, body: IDataObject, maxAttempts = 3): Promise<T2AResponse> {
let lastErr: Error | null = null;
for (let attempt = 0; attempt < maxAttempts; attempt++) {
const response = (await apiRequest.call(this, 'POST', '/t2a_v2', { body })) as T2AResponse;
if (response.base_resp?.status_code !== 0) {
throw new NodeOperationError(this.getNode(), `Text-to-speech failed: ${response.base_resp?.status_msg || 'Unknown error'}`);
}
if (response.data?.audio) return response; // success with payload
lastErr = new Error('No audio data returned; retrying');
await sleep(1000 * (attempt + 1));
}
throw new NodeOperationError(this.getNode(), lastErr?.message ?? 'No audio data returned');
} Prevention
- Treat success-without-audio as transient and retry with backoff before failing the run.
- Log the full response body when it happens so you can distinguish a real API change from a glitch.
- Point credentials at the official MiniMax base URL to avoid proxies that strip fields.
- Keep inputs within documented limits to reduce the chance of partial server-side failure.
When it happens
Trigger: Transient MiniMax backend glitch returning success without audio; API version change that moved audio bytes to a different field; extremely long input where the service partially failed after marking success; response truncated by an intermediary proxy.
Common situations: Rare upstream bug; running against a non-standard base URL (custom proxy/gateway) that strips the data.audio field; stale credentials causing a degraded response; very long text near the limit.
Related errors
- No images were generated
- Text-to-speech failed: ${response.base_resp?.status_msg || '
- No task_id returned from video generation request
- No task_id returned from video generation request
- Video generation succeeded but no file_id was returned
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/cedcf9bd04adff88.
Report an issue: GitHub.