{"record":{"id":"4a3229d2c82e36f0","repo":"stablyai/orca","slug":"file-changed-during-upload-staging-displaypath","errorCode":null,"errorMessage":"File changed during upload staging: '${displayPath}'","messagePattern":"File changed during upload staging: '(.+?)'","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/ipc/filesystem-mutations.ts","lineNumber":604,"sourceCode":"    await assertRealPathInsideRoot(options.rootRealPath, filePath, displayPath)\n  }\n  const initialTotalBytes =\n    options?.totalBytesBefore === undefined\n      ? statResult.size\n      : options.totalBytesBefore + statResult.size\n  assertRemoteUploadBudget(relativePath, statResult.size, initialTotalBytes)\n  const fileHandle = await open(filePath, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0))\n  try {\n    const openedStat = await fileHandle.stat()\n    if (!openedStat.isFile()) {\n      throw new Error(`Unsupported file type in '${displayPath}'`)\n    }\n    if (\n      openedStat.size !== statResult.size ||\n      (statResult.ino !== 0 && openedStat.ino !== 0 && openedStat.ino !== statResult.ino) ||\n      (statResult.dev !== 0 && openedStat.dev !== 0 && openedStat.dev !== statResult.dev)\n    ) {\n      throw new Error(`File changed during upload staging: '${displayPath}'`)\n    }\n    const totalBytes =\n      options?.totalBytesBefore === undefined\n        ? openedStat.size\n        : options.totalBytesBefore + openedStat.size\n    assertRemoteUploadBudget(relativePath, openedStat.size, totalBytes)\n    const buffer = await fileHandle.readFile()\n    const afterReadStat = await fileHandle.stat()\n    if (afterReadStat.size !== openedStat.size) {\n      throw new Error(`File changed during upload staging: '${displayPath}'`)\n    }\n    return {\n      entry: {\n        relativePath: displayPath,\n        kind: 'file',\n        contentBase64: buffer.toString('base64')\n      },\n      byteLength: openedStat.size","sourceCodeStart":586,"sourceCodeEnd":622,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/ipc/filesystem-mutations.ts#L586-L622","documentation":"Thrown in stageFileEntry after O_NOFOLLOW open. The code compares the post-open fstat (size, inode, device) against the pre-scan lstat result. If any field differs, the file was swapped or truncated between the lstat and the open. This pins the authorized file identity so that a race cannot substitute a different file body for the one that was validated.","triggerScenarios":"Between the initial lstat (line 577) and the O_NOFOLLOW open (line 593), a concurrent process replaces, truncates, or moves the file such that size, inode number, or device number changes. The open succeeds but fstat reports a different identity than the lstat.","commonSituations":"A log file being rotated during staging. A file being rewritten by an editor save or build step. NFS or network filesystems where inode/device mapping is unstable. Importing from a watched directory where file-watchers trigger modifications.","solutions":["Re-run the staging when the source tree is quiescent — no concurrent writes.","If the file is a log or output being actively written, snapshot it (copy to a stable temp location) before importing.","On network filesystems, ensure the mount is stable and not remounting during the import."],"exampleFix":"// before: stage a file that is being actively appended to\n// after: snapshot first, then stage the snapshot\n//   cp /var/log/app.log /tmp/stable/app.log\n//   import /tmp/stable/app.log","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await stageRemoteImport(sourcePath)\n} catch (error) {\n  if (error instanceof Error && error.message.includes('File changed during upload staging')) {\n    // file was being written concurrently; retry after a brief pause\n    return stageRemoteImport(sourcePath) // one retry\n  }\n  throw error\n}","preventionTips":["Do not stage files that are being actively written by running processes.","Snapshot log files to a stable copy before staging.","On network filesystems, verify mount stability before importing."],"tags":["toctou","filesystem","upload-staging","security","race-condition","ipc"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}