mudler/LocalAI · error

[moss-tts-cpp] ERROR: moss_local_tts failed\n

Error message

[moss-tts-cpp] ERROR: moss_local_tts failed\n

What it means

moss_local_tts() ran but returned NULL or a non-positive sample count (n <= 0). The engine started synthesis and failed mid-run, or produced zero audio. The shim frees any partial engine buffer and returns nullptr. Distinct from 172/173: inputs were valid and the model was loaded; this is an inference-time failure.

Source

Thrown at backend/go/moss-tts-cpp/cpp/mossttscpp.cpp:84

    if (!g_local) {
        fprintf(stderr, "[moss-tts-cpp] ERROR: model not loaded\n");
        return nullptr;
    }
    if (!text || text[0] == '\0') {
        fprintf(stderr, "[moss-tts-cpp] ERROR: text is required\n");
        return nullptr;
    }

    // An empty reference path means "no cloning": pass NULL so the engine skips
    // the clone branch rather than trying to open "".
    const char *ref = (reference_wav && reference_wav[0] != '\0')
                          ? reference_wav
                          : nullptr;

    int n = 0, sr = 0;
    float *pcm = moss_local_tts(g_local, text, ref, seed, &n, &sr);
    if (!pcm || n <= 0) {
        fprintf(stderr, "[moss-tts-cpp] ERROR: moss_local_tts failed\n");
        if (pcm)
            moss_free(pcm);
        return nullptr;
    }

    // Copy into a plain malloc buffer the Go side frees via mtl_pcm_free, then
    // release the engine-owned buffer with moss_free (mirrors qwen3-tts-cpp,
    // keeping ownership on the C runtime's malloc/free).
    size_t bytes = (size_t)n * sizeof(float);
    float *buf = (float *)malloc(bytes);
    if (!buf) {
        fprintf(stderr, "[moss-tts-cpp] ERROR: malloc(%zu) failed\n", bytes);
        moss_free(pcm);
        return nullptr;
    }
    memcpy(buf, pcm, bytes);
    moss_free(pcm);

View on GitHub (pinned to 44413a9d06)

Solutions

  1. Retry once without the reference_wav (plain synthesis) to isolate the cloning branch.
  2. Inspect engine logs above the error for the failing stage (tokenization vs. decode vs. codec).
  3. Shorten or sanitize the input text; confirm the reference WAV is a valid PCM file the engine supports.
  4. Try a different seed — degenerate zero-length output can be seed-dependent.

Example fix

// before: only clone path
pcm := mtlTTS(text, refWav, seed)
// after: fall back to no-clone synthesis
pcm := mtlTTS(text, refWav, seed)
if pcm == nil { pcm = mtlTTS(text, "", seed) }
Defensive patterns

Strategy: fallback

Validate before calling

if refWav != "" {
    if _, err := os.Stat(refWav); err != nil {
        refWav = "" // drop clone reference rather than fail synthesis
    }
}

Prevention

When it happens

Trigger: Text the engine cannot vocalize (unsupported script/language), a reference_wav that fails to load or is incompatible for voice cloning, numerical/backend faults during decoding, or seed-dependent generation collapsing to zero length.

Common situations: Cloning with a corrupt or wrong-format reference WAV; text entirely in a script Moss TTS does not support; GPU backend numerical issues; very long text overflowing engine limits.

Related errors


AI-assisted analysis of mudler/LocalAI@44413a9d06 (2026-08-15). Data as JSON: /api/errors/641c06e420c1176a. Report an issue: GitHub.