{"record":{"id":"011c8d1c1282f59c","repo":"gohugoio/hugo","slug":"webpanimencoderassemble-failed-n","errorCode":null,"errorMessage":"WebPAnimEncoderAssemble failed\\n","messagePattern":"WebPAnimEncoderAssemble failed\\\\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/warpc/genwebp/webp.c","lineNumber":263,"sourceCode":"            WebPAnimEncoderDelete(enc);\n            return NULL;\n        }\n        timestamp += params.frameDurations[i];\n        WebPPictureFree(&pic);\n    }\n\n    if (!WebPAnimEncoderAdd(enc, NULL, timestamp, config))\n    {\n        fprintf(stderr, \"WebPAnimEncoderAdd failed for final frame\\n\");\n        WebPAnimEncoderDelete(enc);\n        return NULL;\n    }\n\n    WebPData webp_data_out;\n    WebPDataInit(&webp_data_out);\n    if (!WebPAnimEncoderAssemble(enc, &webp_data_out))\n    {\n        fprintf(stderr, \"WebPAnimEncoderAssemble failed\\n\");\n        WebPAnimEncoderDelete(enc);\n        return NULL;\n    }\n    WebPAnimEncoderDelete(enc);\n\n    *output_size = webp_data_out.size;\n    uint8_t *webp_data = malloc(*output_size);\n    if (webp_data == NULL)\n    {\n        fprintf(stderr, \"malloc failed for final webp data\\n\");\n        WebPDataClear(&webp_data_out);\n        return NULL;\n    }\n    memcpy(webp_data, webp_data_out.bytes, *output_size);\n    WebPDataClear(&webp_data_out);\n\n    return webp_data;\n}","sourceCodeStart":245,"sourceCodeEnd":281,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/internal/warpc/genwebp/webp.c#L245-L281","documentation":"Printed by genwebp's encodeNRGBAAnimated (webp.c:263) when WebPAnimEncoderAssemble returns false. Assemble walks the accumulated frames and produces the final RIFF-formatted WebP byte stream; failure indicates an internal encoder error, typically memory allocation failure while building the container, or an encoder that was left in an invalid state. The worker deletes the encoder and returns NULL.","triggerScenarios":"All frames added successfully and the flush sentinel succeeded, but assembling the final container failed: OOM while allocating the output WebPData, internal inconsistency in the anim encoder state, or a libwebp version bug in the assemble path.","commonSituations":"Animations with many frames whose assembled output is very large, low-memory worker containers, or a libwebp build/runtime mismatch that corrupts internal encoder state.","solutions":["Reduce animation size (fewer frames or smaller canvas) to shrink the assembled output.","Raise the worker memory limit and watch RSS during assemble with /usr/bin/time -v.","Rebuild against a current libwebp and re-test the same input.","If the input is pathological (thousands of tiny frames), pre-coalesce or drop redundant frames before encoding.","Fall back to a non-animated output format for inputs that consistently fail assemble."],"exampleFix":"# before: 500-frame animation, assemble fails OOM in a 128MB container\n$ convert big.gif out.webp\n\n# after: raise worker memory and cap frame count\n# docker/compose: mem_limit: 1g\n# Hugo side: drop frames beyond a cap before encoding\nif frameCount > 200 { frames = frames[:200] }","handlingStrategy":"fallback","validationCode":"// Cap animated output size; if exceeded, skip animated WebP.\nconst maxFrames = 200\nfunc maybeTrimFrames(frames []Frame) []Frame {\n    if len(frames) > maxFrames { return frames[:maxFrames] }\n    return frames\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Limit frame count and canvas to keep the assembled output within memory.","Run only one animated encode at a time per worker to bound peak RSS.","Raise the worker memory limit for known-large inputs.","Rebuild against a current libwebp to rule out assemble-path bugs."],"tags":["webp","animation","encoding","assemble","oom","libwebp"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}