{"record":{"id":"2178175ecf05c547","repo":"mudler/LocalAI","slug":"moss-tts-cpp-error-malloc-zu-failed-n","errorCode":null,"errorMessage":"[moss-tts-cpp] ERROR: malloc(%zu) failed\\n","messagePattern":"\\[moss-tts-cpp\\] ERROR: malloc\\(%zu\\) failed\\\\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/go/moss-tts-cpp/cpp/mossttscpp.cpp","lineNumber":96,"sourceCode":"                          ? reference_wav\n                          : nullptr;\n\n    int n = 0, sr = 0;\n    float *pcm = moss_local_tts(g_local, text, ref, seed, &n, &sr);\n    if (!pcm || n <= 0) {\n        fprintf(stderr, \"[moss-tts-cpp] ERROR: moss_local_tts failed\\n\");\n        if (pcm)\n            moss_free(pcm);\n        return nullptr;\n    }\n\n    // Copy into a plain malloc buffer the Go side frees via mtl_pcm_free, then\n    // release the engine-owned buffer with moss_free (mirrors qwen3-tts-cpp,\n    // keeping ownership on the C runtime's malloc/free).\n    size_t bytes = (size_t)n * sizeof(float);\n    float *buf = (float *)malloc(bytes);\n    if (!buf) {\n        fprintf(stderr, \"[moss-tts-cpp] ERROR: malloc(%zu) failed\\n\", bytes);\n        moss_free(pcm);\n        return nullptr;\n    }\n    memcpy(buf, pcm, bytes);\n    moss_free(pcm);\n\n    if (out_n)\n        *out_n = n;\n    if (out_sr)\n        *out_sr = sr;\n    return buf;\n}\n\nvoid mtl_pcm_free(float *p) { free(p); }\n\nvoid mtl_unload(void) {\n    if (g_local) {\n        moss_local_free(g_local);","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/mudler/LocalAI/blob/44413a9d06bf5bc52ce088ba8ca74e5a2e8bee26/backend/go/moss-tts-cpp/cpp/mossttscpp.cpp#L78-L114","documentation":"The malloc of n * sizeof(float) bytes for the PCM copy-out buffer failed (OOM at the C heap). Synthesis itself succeeded — engine pcm was produced — but the shim cannot hand a copy to the Go side, so it frees the engine buffer and returns nullptr. Indicates process address-space or memory exhaustion proportional to the generated audio length.","triggerScenarios":"Very long synthesis (huge n) on a process already near its memory ceiling; cgo/purego process with a fragmented heap; container memory limit hit at the moment of the copy.","commonSituations":"Generating long-form speech in a memory-capped container alongside resident model weights; 32-bit builds where address space runs out; repeated long generations fragmenting the heap.","solutions":["Reduce requested audio length or chunk long text into multiple shorter syntheses.","Raise the container/process memory limit or free other loaded backends.","Stream via chunked output if the engine supports it rather than one giant buffer.","Check for leaked buffers on the Go side (mtl_pcm_free must be called on every returned pointer)."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// cap requested length before synthesis so the copy buffer stays bounded\nconst maxSamples = 48_000 * 300 // ~5 min\nif estSamples(text) > maxSamples {\n    return nil, errors.New(\"requested audio too long; chunk the text\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Chunk long text into multiple shorter syntheses.","Free every returned buffer via mtl_pcm_free to avoid heap growth across requests.","Size container memory for model weights plus the largest expected audio buffer."],"tags":["moss-tts-cpp","tts","oom","memory"],"backgroundTag":null,"analyzedSha":"44413a9d06bf5bc52ce088ba8ca74e5a2e8bee26","analyzedAt":"2026-08-15T10:13:50.291Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}