{"record":{"id":"e9ef4bb485306417","repo":"denoland/deno","slug":"unexpected-end-of-bytes","errorCode":null,"errorMessage":"unexpected end of bytes","messagePattern":"unexpected end of bytes","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"libs/eszip/v2.rs","lineNumber":1898,"sourceCode":"  let (input, name) = move_bytes(input, size as usize)?;\n  let text = String::from_utf8(name.to_vec()).map_err(|_| {\n    std::io::Error::new(std::io::ErrorKind::InvalidData, \"invalid utf-8 data\")\n  })?;\n  Ok((input, text))\n}\n\nfn parse_u32(input: &[u8]) -> std::io::Result<(&[u8], u32)> {\n  let (input, value_bytes) = move_bytes(input, 4)?;\n  let value = u32::from_be_bytes(value_bytes.try_into().unwrap());\n  Ok((input, value))\n}\n\nfn move_bytes(\n  bytes: &[u8],\n  len: usize,\n) -> Result<(&[u8], &[u8]), std::io::Error> {\n  if bytes.len() < len {\n    Err(std::io::Error::new(\n      std::io::ErrorKind::UnexpectedEof,\n      \"unexpected end of bytes\",\n    ))\n  } else {\n    Ok((&bytes[len..], &bytes[..len]))\n  }\n}\n\n#[derive(Debug)]\nstruct Section(Vec<u8>, Options);\n\nimpl Section {\n  /// Reads a section that's defined as:\n  ///   Size (4) | Body (n) | Hash (32)\n  async fn read<R: futures::io::AsyncRead + Unpin>(\n    mut reader: R,\n    options: Options,\n  ) -> Result<Section, ParseError> {","sourceCodeStart":1880,"sourceCodeEnd":1916,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/libs/eszip/v2.rs#L1880-L1916","documentation":"eszip v2 parser helper move_bytes: every length-prefixed field (u32 sizes, string bytes, package table entries) slices the input by declared length; if fewer bytes remain than the declared length requires, parsing stops with ErrorKind::UnexpectedEof and this message. It is the generic signature of a truncated eszip archive.","triggerScenarios":"An eszip file cut short relative to its internal section lengths: interrupted `deno compile`, partial download/copy, cache file truncated by disk-full, or a producer version mismatch writing headers that promise more bytes than follow.","commonSituations":"CI caching partial artifacts; deploys interrupted mid-copy; disk quota hit while writing the npm cache; artifacts generated by an older/newer eszip version with incompatible layout.","solutions":["Regenerate the eszip/compiled binary from source with a current Deno version.","Clear the affected cache (DENO_DIR, downloaded artifacts) and re-download fully.","Add post-copy integrity checks (size + hash) in CI before an artifact is used.","Ensure the producing step completes (check exit codes, disk space) before publishing artifacts."],"exampleFix":"# before\nscp -r artifacts/ host:/app/        # copy interrupted -> truncated eszip\n/app/binary run                     # unexpected end of bytes\n\n# after\ndeno compile -o artifacts/app main.ts\nsha256sum artifacts/app > artifacts/app.sha256\n# after transfer:\nsha256sum -c artifacts/app.sha256 && /app/artifacts/app","handlingStrategy":"fallback","validationCode":"const expectedBytes = 1_234_567; // recorded at build time\nconst st = await stat(artifact);\nif (st.size !== expectedBytes) throw new Error(`artifact truncated: ${st.size} != ${expectedBytes} bytes`);","typeGuard":null,"tryCatchPattern":"try { await run(); } catch (e) { if (/unexpected end of bytes/.test(String(e))) { await regenerateArtifact(); } else throw e; }","preventionTips":["Check exit codes and disk space in the step that produces eszips/compiled binaries.","Write artifacts atomically (tmp file + rename) so partial writes never look complete.","Verify artifact size/hash after copy/deploy steps, before first execution."],"tags":["eszip","truncation","eof","npm-cache","compile-artifact"],"backgroundTag":"truncated-file","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-31T04:17:50.494Z"}