{"record":{"id":"8fb36d4912e24af7","repo":"gohugoio/hugo","slug":"d-error-reading-blob-data-size-llu-read-z-8fb36d","errorCode":null,"errorMessage":"[%d]  Error reading blob data (size: %llu read: %zu) \\n","messagePattern":"\\[(.+?)\\]  Error reading blob data \\(size: %llu read: %zu\\) \\\\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/warpc/genwebp/webp.c","lineNumber":593,"sourceCode":"        blob_size = *(uint32_t *)&blob_header[12];\n        blob_data = malloc((size_t)blob_size);\n        if (blob_data == NULL)\n        {\n            // Out of memory. Drain the blob from the input stream so the next\n            // command stays aligned, then report the error to the client instead\n            // of leaving the stream corrupted with no response.\n            drain_bytes(stream, (size_t)blob_size);\n            OutputMessage err_output = {0};\n            err_output.header = input.header;\n            snprintf(err_output.header.err, sizeof(err_output.header.err),\n                     \"out of memory allocating %u bytes for blob data\", blob_size);\n            write_output_message(&err_output);\n            goto cleanup;\n        }\n        read_bytes = fread(blob_data, 1, (size_t)blob_size, stream);\n        if (read_bytes != (size_t)blob_size)\n        {\n            fprintf(stderr, \"[%d]  Error reading blob data (size: %llu read: %zu) \\n\", blob_id, (unsigned long long)blob_size, read_bytes);\n            goto cleanup;\n        }\n\n        OutputMessage output = {0};\n        output.header = input.header;\n\n        if (strcmp(input.header.command, \"decode\") == 0)\n        {\n\n            WebPData data;\n            data.bytes = blob_data;\n            data.size = (size_t)blob_size;\n\n            WebPDecoderConfig config;\n            if (!initDecoderConfig(&config, data))\n            {\n                strncpy(output.header.err, \"Failed to initialize WebPDecoderConfig\", sizeof(output.header.err) - 1);\n                write_output_message(&output);","sourceCodeStart":575,"sourceCodeEnd":611,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/internal/warpc/genwebp/webp.c#L575-L611","documentation":"Printed by genwebp's handle_commands (webp.c:593) when the blob header's declared size does not match the bytes fread returned. Logs blob_id, declared size, and actual read count. Identical semantics to the genavif counterpart (823): the canonical stream-desync signal for genwebp.","triggerScenarios":"Header size field disagrees with the bytes the host wrote (wrong stride*width*height, wrong bytes-per-pixel for has_alpha, endianness packing error), host closed the pipe partway through the blob, or a previous over-read advanced the stream past the true blob start.","commonSituations":"RGB vs RGBA byte-count mismatch (3 vs 4 bytes/pixel), animated frame count differing from declared, partial write from a flushed buffered writer, stale cached size after the source image changed, or test fixtures with a hardcoded size field.","solutions":["Compute size from the actual byte length of the payload about to be written: size := uint32(len(pix)).","For animated encodes, size = stride*height*frameCount, with stride = width*4 for RGBA.","Treat any partial write (n != len) from the Go writer as fatal.","On Go-side errors mid-send, close and respawn the worker rather than reusing a half-drained pipe.","Log the declared size at send time and correlate with the size printed here."],"exampleFix":"// before: size hardcoded / cached, mismatches actual payload\nsize := uint32(1024 * 1024) // stale\nbinary.LittleEndian.PutUint32(hdr[12:], size)\n\n// after\npix := flattenRGBA(frames, w, h, frameCount)\nsize := uint32(len(pix))\nbinary.LittleEndian.PutUint32(hdr[12:], size)\nw.Write(hdr); w.Write(pix)","handlingStrategy":"validation","validationCode":"func webpBlobHeader(id uint32, payload []byte) []byte {\n    h := make([]byte, 16)\n    copy(h[0:8], []byte(\"TAK35EM1\"))\n    binary.LittleEndian.PutUint32(h[8:12], id)\n    binary.LittleEndian.PutUint32(h[12:16], uint32(len(payload)))\n    return h\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Derive size from len(payload), not from a cached field.","For RGBA: payload length = width*4*height (or *frameCount for animated).","Treat any partial write as fatal and respawn the worker.","Log declared size at send time to correlate with the worker's stderr print."],"tags":["rpc","io","protocol","webp","stream-desync","sizing"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}