{"record":{"id":"84cf380c0dc79fc0","repo":"Hmbown/CodeWhale","slug":"malformed-jpeg-at-byte-at-file","errorCode":null,"errorMessage":"malformed JPEG at byte ${at}: ${file}","messagePattern":"malformed JPEG at byte (.+?): (.+?)","errorType":"exception","errorClass":"ExecError","httpStatus":null,"severity":"error","filePath":"crates/tui/plugins/computer-use/src/backends/darwin.mjs","lineNumber":49,"sourceCode":" * Pixel dimensions from a PNG IHDR or a JPEG frame header, reading only the\n * bytes that carry them rather than the whole raster.\n */\nfunction imagePixels(file) {\n  const fd = fs.openSync(file, \"r\");\n  try {\n    const head = Buffer.alloc(24);\n    fs.readSync(fd, head, 0, 24, 0);\n    if (head[0] === 0x89 && head.toString(\"ascii\", 1, 4) === \"PNG\") {\n      return { w: head.readUInt32BE(16), h: head.readUInt32BE(20) };\n    }\n    if (head[0] !== 0xff || head[1] !== 0xd8) throw new ExecError(`unrecognized raster format: ${file}`);\n    // Walk JPEG segments to the frame header. SOF0/1/2/3/5..7/9..11/13..15\n    // carry the dimensions; DHT/DQT and the rest are skipped by their length.\n    const size = fs.fstatSync(fd).size;\n    const seg = Buffer.alloc(9);\n    for (let at = 2; at + 9 <= size; ) {\n      fs.readSync(fd, seg, 0, 9, at);\n      if (seg[0] !== 0xff) throw new ExecError(`malformed JPEG at byte ${at}: ${file}`);\n      const marker = seg[1];\n      if (marker >= 0xc0 && marker <= 0xcf && marker !== 0xc4 && marker !== 0xc8 && marker !== 0xcc) {\n        return { w: seg.readUInt16BE(7), h: seg.readUInt16BE(5) };\n      }\n      if (marker === 0xd8 || (marker >= 0xd0 && marker <= 0xd9)) { at += 2; continue; }\n      at += 2 + seg.readUInt16BE(2);\n    }\n    throw new ExecError(`JPEG carries no frame header: ${file}`);\n  } finally {\n    fs.closeSync(fd);\n  }\n}\n\n/**\n * Shrink a raster until it fits the single-message budget.\n *\n * A 5K display captures to ~22MB of PNG, which is ~29MB of base64 — past every\n * host limit, so the alternative is handing back a receipt with no picture and","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/plugins/computer-use/src/backends/darwin.mjs#L31-L67","documentation":"While walking JPEG segment markers to find the SOFn frame header (which carries width/height), `imagePixels` expects every segment to begin with the 0xFF marker byte. If the byte at the current offset is not 0xFF, the file is not a well-formed JPEG and `malformed JPEG at byte <at>: <file>` is thrown.","triggerScenarios":"A file that starts with the JPEG SOI magic (0xFF 0xD8) but is corrupted or truncated afterwards — mid-stream corruption, a partially written screenshot, or appended/truncated data shifting segment lengths.","commonSituations":"Disk-full during capture leaving a truncated JPEG, a file still being written by the capture process when dimensions are read, or bit-flips from a bad transfer.","solutions":["Re-capture or re-copy the screenshot; the file is corrupt.","Wait for the capture process to finish writing before reading dimensions.","Verify the JPEG with a decoder (e.g. `sips -g pixelWidth`) to confirm corruption.","Add a readiness check (file size stable across two stats) before reading."],"exampleFix":"// before\\nimagePixels(shotPath); // file may still be flushing\\n// after\\nawait waitForFileSettled(shotPath);\\nimagePixels(shotPath);","handlingStrategy":"fallback","validationCode":"// confirm the file is settled before parsing\\nconst s1 = fs.statSync(file).size;\\nawait sleep(150);\\nif (fs.statSync(file).size !== s1) throw new Error(\"file still being written\");","typeGuard":null,"tryCatchPattern":"try { return imagePixels(file); } catch (e) { if (/malformed JPEG/.test(e.message)) { await recaptureScreenshot(file); return imagePixels(file); } throw e; }","preventionTips":["Ensure capture completes (process exit or size stability) before reading.","Write screenshots atomically (temp file + rename).","Periodically verify captured files decode with sips."],"tags":["image","jpeg","corruption","darwin"],"backgroundTag":"file-read-failed","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}