{"record":{"id":"fe87d58f5c91f034","repo":"ruvnet/ruflo","slug":"file-too-large-stats-size-maxsize","errorCode":null,"errorMessage":"File too large: ${stats.size} > ${maxSize}","messagePattern":"File too large: (.+?) > (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/hooks/src/workers/index.ts","lineNumber":153,"sourceCode":"  if (fileCache.size > 100) {\n    for (const [key, entry] of fileCache) {\n      if (entry.expires < now) {\n        fileCache.delete(key);\n      }\n    }\n  }\n\n  return content;\n}\n\n/**\n * Safe file read with size limit\n */\nasync function safeReadFile(filePath: string, maxSize = MAX_FILE_SIZE): Promise<string> {\n  try {\n    const stats = await fs.stat(filePath);\n    if (stats.size > maxSize) {\n      throw new Error(`File too large: ${stats.size} > ${maxSize}`);\n    }\n    return await fs.readFile(filePath, 'utf-8');\n  } catch (error) {\n    if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n      throw new Error('File not found');\n    }\n    throw error;\n  }\n}\n\n/**\n * Validate project root is a real directory\n */\nasync function validateProjectRoot(root: string): Promise<string> {\n  const resolved = path.resolve(root);\n  try {\n    const stats = await fs.stat(resolved);\n    if (!stats.isDirectory()) {","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/hooks/src/workers/index.ts#L135-L171","documentation":"Thrown by safeReadFile() in @claude-flow/hooks workers (v3/@claude-flow/hooks/src/workers/index.ts:153) when fs.stat reports a file larger than maxSize. The default limit is MAX_FILE_SIZE = 10MB (10 * 1024 * 1024 at index.ts:17); the persistence loader calls it with a tighter 1MB limit (index.ts:478). It exists to stop a huge or corrupt file from being fully read into memory as a UTF-8 string.","triggerScenarios":"Reading a persisted worker-state file (this.persistPath) that grew past 1MB because the worker accumulated many entries; reading any config/log file over 10MB via the default; a truncated-then-appended JSON state file after a crash that ballooned in size.","commonSituations":"Long-running hook sessions whose worker persistence file grows unbounded; logs or JSONL dumps accidentally pointed at the reader; forgetting that the persist path uses a 1MB cap, not 10MB.","solutions":["Check the file size with fs.stat before calling safeReadFile and handle the oversize case (truncate, rotate, or archive the file).","If the file is legitimately large and trusted, pass an explicit higher maxSize: await safeReadFile(p, 50 * 1024 * 1024).","For the 1MB persistPath limit specifically, prune/compact the persisted worker state (drop old checkpoints/entries) so it stays under 1MB.","Investigate why the file grew — unbounded append instead of atomic rewrite is the usual root cause."],"exampleFix":"// before\nconst content = await safeReadFile(this.persistPath, 1024 * 1024);\n\n// after\nconst st = await fs.stat(this.persistPath);\nif (st.size > 1024 * 1024) {\n  await fs.rename(this.persistPath, `${this.persistPath}.bak-${Date.now()}`);\n  // start from a fresh state file\n}\nconst content = await safeReadFile(this.persistPath, 1024 * 1024);","handlingStrategy":"validation","validationCode":"const st = await fs.stat(filePath);\nif (st.size > limit) {\n  // rotate or truncate before reading\n  await fs.rename(filePath, `${filePath}.oversize-${Date.now()}`);\n}","typeGuard":"async function isReadableSize(filePath: string, max: number): Promise<boolean> {\n  const st = await fs.stat(filePath);\n  return st.size <= max;\n}","tryCatchPattern":"try {\n  content = await safeReadFile(p, max);\n} catch (e) {\n  if (/^File too large/.test((e as Error).message)) { /* rotate + retry once */ }\n  else throw e;\n}","preventionTips":["Remember the 1MB cap on worker persistence files vs the 10MB default elsewhere.","Compact/rotate state files on a schedule so they never approach the limit.","Write state atomically (temp file + rename) instead of appending, so files do not grow unbounded."],"tags":["file-size-limit","filesystem","resource-limit"],"backgroundTag":"file-size-limit-exceeded","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}