{"record":{"id":"a4845a7dc8604ab5","repo":"run-llama/liteparse","slug":"invalid-rgb-buffer-length-for-width-x-height-ex","errorCode":null,"errorMessage":"invalid RGB buffer length for {width}x{height}: expected {expected_len} bytes, got {}","messagePattern":"invalid RGB buffer length for (.+?)x(.+?): expected (.+?) bytes, got (.+?)","errorType":"validation","errorClass":"std::io::Error","httpStatus":null,"severity":"error","filePath":"crates/liteparse/src/ocr/oar.rs","lineNumber":277,"sourceCode":"    if width == 0 || height == 0 {\n        return Err(io::Error::new(\n            io::ErrorKind::InvalidInput,\n            format!(\"invalid zero-sized RGB image: {width}x{height}\"),\n        ));\n    }\n\n    let expected_len = (width as usize)\n        .checked_mul(height as usize)\n        .and_then(|pixels| pixels.checked_mul(3))\n        .ok_or_else(|| {\n            io::Error::new(\n                io::ErrorKind::InvalidInput,\n                format!(\"RGB image dimensions overflow: {width}x{height}\"),\n            )\n        })?;\n\n    if image_data.len() != expected_len {\n        return Err(io::Error::new(\n            io::ErrorKind::InvalidInput,\n            format!(\n                \"invalid RGB buffer length for {width}x{height}: expected {expected_len} bytes, got {}\",\n                image_data.len()\n            ),\n        ));\n    }\n\n    image::RgbImage::from_raw(width, height, image_data.to_vec()).ok_or_else(|| {\n        io::Error::new(\n            io::ErrorKind::InvalidInput,\n            format!(\"failed to construct RGB image from {width}x{height} buffer\"),\n        )\n    })\n}\n\nfn region_to_result(region: oar_ocr::oarocr::TextRegion) -> Option<OcrResult> {\n    let text = region.text?.trim().to_owned();","sourceCodeStart":259,"sourceCodeEnd":295,"githubUrl":"https://github.com/run-llama/liteparse/blob/22d2dd8cd7f7b9320102b57ddaf0e663ff7d15a8/crates/liteparse/src/ocr/oar.rs#L259-L295","documentation":"rgb_image requires the byte slice to contain exactly width * height * 3 bytes (one RGB triple per pixel). When image_data.len() differs from the expected length, the buffer and the declared dimensions disagree, so the call is rejected with this InvalidInput error naming both expected and actual sizes. This is a strict contract check before constructing the RgbImage.","triggerScenarios":"Calling the OCR recognize path with a buffer whose length does not match width*height*3 — e.g. passing RGBA data (4 bytes/pixel) as RGB, passing grayscale data, or passing dimensions from a different image than the buffer.","commonSituations":"Mixing up RGBA and RGB buffers when piping decoded image data to OCR; OCR servers returning raw buffers with stride/padding; copying dimensions from one decoded image and bytes from another.","solutions":["Convert the buffer to strict 3-bytes-per-pixel RGB before calling (drop the alpha channel, remove row stride/padding).","Recompute width/height from the actual buffer (len/3, with a known aspect) so they match.","Ensure the dimensions and the byte buffer come from the same decoded image."],"exampleFix":"// before: RGBA buffer passed as RGB\nlet rgba = decoded.to_rgba8();\nocr.recognize_sync(rgba.as_raw(), decoded.width(), decoded.height())?;\n\n// after: convert to RGB first\nlet rgb = DynamicImage::ImageRgba8(decoded.to_rgba8()).to_rgb8();\nocr.recognize_sync(rgb.as_raw(), rgb.width(), rgb.height())?;","handlingStrategy":"validation","validationCode":"// Rust: assert RGB (3 bytes/pixel) buffer length matches dims\nfn rgb_len_ok(data: &[u8], w: u32, h: u32) -> bool {\n    data.len() == w as usize * h as usize * 3\n}","typeGuard":"fn as_exact_rgb(data: &[u8], w: u32, h: u32)\n    -> Option<&[u8]>\n{\n    let expected = (w as usize).checked_mul(h as usize)?.checked_mul(3)?;\n    (data.len() == expected).then_some(data)\n}","tryCatchPattern":null,"preventionTips":["Always convert RGBA/grayscale buffers to strict RGB before OCR","Derive width/height and bytes from the same decoded image object","Strip row stride/padding before passing raw buffers"],"tags":["ocr","buffer-length-mismatch","image-validation","rust"],"backgroundTag":"shape-mismatch","analyzedSha":"22d2dd8cd7f7b9320102b57ddaf0e663ff7d15a8","analyzedAt":"2026-09-08T06:09:49.009Z","contentChangedAt":"2026-09-08T06:09:49.009Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}