{"record":{"id":"229c999beb939a4c","repo":"nexu-io/open-design","slug":"xai-tts-resp-status-truncate-errtext-240","errorCode":null,"errorMessage":"xai tts ${resp.status}: ${truncate(errText, 240)}","messagePattern":"xai tts (.+?): (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/daemon/src/media/index.ts","lineNumber":2504,"sourceCode":"  // we want. Future work: surface sample_rate / bit_rate / codec via\n  // ctx so the agent can request wav for high-fidelity workflows.\n  const body = {\n    text,\n    voice_id: voiceId,\n    language,\n  };\n\n  const resp = await fetch(`${baseUrl}/tts`, withMediaRequestInit(ctx, {\n    method: 'POST',\n    headers: {\n      authorization: `Bearer ${credentials.apiKey}`,\n      'content-type': 'application/json',\n    },\n    body: JSON.stringify(body),\n  }));\n  if (!resp.ok) {\n    const errText = await resp.text().catch(() => '');\n    throw new Error(`xai tts ${resp.status}: ${truncate(errText, 240)}`);\n  }\n  const arrayBuffer = await resp.arrayBuffer();\n  const bytes = Buffer.from(arrayBuffer);\n  if (bytes.length === 0) {\n    throw new Error('xai tts response had zero bytes');\n  }\n  return {\n    bytes,\n    providerNote: `xai/${ctx.wireModel} · voice=${voiceId} · ${language} · ${bytes.length} bytes`,\n    suggestedExt: '.mp3',\n  };\n}\n\n// ---------------------------------------------------------------------------\n// Provider: ElevenLabs — v3 text-to-speech (synchronous).\n//\n// Docs: https://elevenlabs.io/docs/api-reference/text-to-speech/convert\n// The API returns MP3 bytes directly. The catalogue id `elevenlabs-v3`","sourceCodeStart":2486,"sourceCodeEnd":2522,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/media/index.ts#L2486-L2522","documentation":"Thrown by renderXAITTS() after POST {baseUrl}/tts returns a non-2xx response. The error embeds the HTTP status code and the first 240 characters of the response body (via truncate), so the upstream xAI error is surfaced rather than swallowed. This is the only signal of provider-side rejection (bad voice id, invalid language, rate limit, auth failure).","triggerScenarios":"xAI rejects the TTS request: 401/403 for bad or expired token, 400 for an unsupported voice_id or language, 429 for rate limiting, 5xx for provider outage, or a wrong baseUrl pointing at a non-xAI host.","commonSituations":"OAuth token expired; voice_id does not exist on the user's plan; language code not supported; baseUrl override points at a proxy that returns its own error shape; rate limit hit during batch generation; xAI incident.","solutions":["Read the embedded status and body text: 401/403 means re-authorize via hermes auth add xai-oauth or refresh XAI_API_KEY","For 400, check that ctx.voice (voice_id) and ctx.language are values xAI accepts; fall back to defaults (eve / en) by clearing the overrides","For 429, back off and retry with fewer concurrent TTS requests","For 5xx, retry after a short delay; check the xAI status page","Confirm credentials.baseUrl is either unset (uses https://api.x.ai/v1) or points at a valid xAI-compatible endpoint"],"exampleFix":"// before: voice override that xAI rejects\nconst ctx = { prompt: 'hello', voice: 'nonexistent-voice', wireModel: 'grok-tts' };\n// after: omit voice to use the documented default 'eve'\nconst ctx = { prompt: 'hello', wireModel: 'grok-tts' };","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function isXaiTtsHttpError(err: unknown): boolean {\n  return err instanceof Error && /^xai tts \\d{3}:/.test(err.message);\n}","tryCatchPattern":"try {\n  const result = await renderXAITTS(ctx, credentials);\n} catch (err) {\n  if (err instanceof Error && /^xai tts (\\d{3}):/.test(err.message)) {\n    const status = Number(RegExp.$1);\n    if (status === 401 || status === 403) await refreshXaiCredentials();\n    else if (status === 429) await backoffThenRetry();\n    else throw err;\n  } else throw err;\n}","preventionTips":["Validate voice_id and language against xAI's documented values before sending","Implement token refresh on 401/403 so expired OAuth does not surface as a hard failure","Add exponential backoff for 429 responses on batch TTS jobs","Keep baseUrl at the default unless a verified proxy is required"],"tags":["network","xai","tts","http-error","upstream"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}