{"record":{"id":"78e72522c1e9e86d","repo":"denoland/deno","slug":"an-attempt-was-made-to-move-the-file-pointer-befor","errorCode":null,"errorMessage":"An attempt was made to move the file pointer before the beginning of the file.","messagePattern":"An attempt was made to move the file pointer before the beginning of the file\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/rt/file_system.rs","lineNumber":1334,"sourceCode":"}\n\npub struct FileBackedVfsFile {\n  file: VirtualFile,\n  pos: RefCell<u64>,\n  vfs: Arc<FileBackedVfs>,\n}\n\nimpl FileBackedVfsFile {\n  pub fn seek(&self, pos: SeekFrom) -> std::io::Result<u64> {\n    match pos {\n      SeekFrom::Start(pos) => {\n        *self.pos.borrow_mut() = pos;\n        Ok(pos)\n      }\n      SeekFrom::End(offset) => {\n        if offset < 0 && -offset as u64 > self.file.offset.len {\n          let msg = \"An attempt was made to move the file pointer before the beginning of the file.\";\n          Err(std::io::Error::new(\n            std::io::ErrorKind::PermissionDenied,\n            msg,\n          ))\n        } else {\n          let mut current_pos = self.pos.borrow_mut();\n          *current_pos = if offset >= 0 {\n            self.file.offset.len - (offset as u64)\n          } else {\n            self.file.offset.len + (-offset as u64)\n          };\n          Ok(*current_pos)\n        }\n      }\n      SeekFrom::Current(offset) => {\n        let mut current_pos = self.pos.borrow_mut();\n        if offset >= 0 {\n          *current_pos += offset as u64;\n        } else if -offset as u64 > *current_pos {","sourceCodeStart":1316,"sourceCodeEnd":1352,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/cli/rt/file_system.rs#L1316-L1352","documentation":"Raised by `FileBackedVfsFile::seek` when a `SeekFrom::End(offset)` call would place the read pointer before byte 0: the negative offset's magnitude exceeds the file's length. The VFS rejects it with `io::ErrorKind::PermissionDenied` (the classic Windows `ERROR_NEGATIVE_SEEK` message) instead of letting the position underflow.","triggerScenarios":"Calling `file.seek(SeekFrom::End(-n))` (Rust) or `file.seek(-n, Deno.SeekMode.End)` (JS) where n is greater than the file's byte length, on a file opened from the embedded VFS of a compiled binary. Any negative offset on an empty file also triggers it.","commonSituations":"Rewinding a fixed block size (e.g. seek -4096 to re-read a footer) on files smaller than that block; ported parsers that assume seek-before-start clamps to 0; truncated input files.","solutions":["Clamp the offset to the file length: seek to `-Math.min(n, len)` after reading `len` from `file.stat()`.","Use `SeekFrom::Start` / `Deno.SeekMode.Start` when the absolute target position is known.","Validate input file size before running seek-based parsing and reject truncated files early."],"exampleFix":"// before\nawait file.seek(-4096, Deno.SeekMode.End); // throws if file < 4096 bytes\n\n// after\nconst { size } = await file.stat();\nawait file.seek(-Math.min(4096, size), Deno.SeekMode.End);","handlingStrategy":"validation","validationCode":"// before any negative End seek\nconst { size } = await file.stat();\nconst safe = Math.min(requestedBackstep, size);\nawait file.seek(-safe, Deno.SeekMode.End);","typeGuard":null,"tryCatchPattern":"try {\n  await file.seek(-n, Deno.SeekMode.End);\n} catch (err) {\n  if (err instanceof Deno.errors.PermissionDenied) { /* clamp and retry once */ }\n  else throw err;\n}","preventionTips":["Never assume file length; always read size from stat before relative seeks","Prefer absolute SeekMode.Start positions in parsers","Treat seek-past-start as malformed input and report the file/offset in the error"],"tags":["vfs","file-seek","negative-offset","standalone-binary"],"backgroundTag":"seek-before-beginning-of-file","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}