ruvnet/ruflo · error

File too large: ${stats.size} > ${maxSize}

Error message

File too large: ${stats.size} > ${maxSize}

What it means

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.

Source

Thrown at v3/@claude-flow/hooks/src/workers/index.ts:153

  if (fileCache.size > 100) {
    for (const [key, entry] of fileCache) {
      if (entry.expires < now) {
        fileCache.delete(key);
      }
    }
  }

  return content;
}

/**
 * Safe file read with size limit
 */
async function safeReadFile(filePath: string, maxSize = MAX_FILE_SIZE): Promise<string> {
  try {
    const stats = await fs.stat(filePath);
    if (stats.size > maxSize) {
      throw new Error(`File too large: ${stats.size} > ${maxSize}`);
    }
    return await fs.readFile(filePath, 'utf-8');
  } catch (error) {
    if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
      throw new Error('File not found');
    }
    throw error;
  }
}

/**
 * Validate project root is a real directory
 */
async function validateProjectRoot(root: string): Promise<string> {
  const resolved = path.resolve(root);
  try {
    const stats = await fs.stat(resolved);
    if (!stats.isDirectory()) {

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Check the file size with fs.stat before calling safeReadFile and handle the oversize case (truncate, rotate, or archive the file).
  2. If the file is legitimately large and trusted, pass an explicit higher maxSize: await safeReadFile(p, 50 * 1024 * 1024).
  3. For the 1MB persistPath limit specifically, prune/compact the persisted worker state (drop old checkpoints/entries) so it stays under 1MB.
  4. Investigate why the file grew — unbounded append instead of atomic rewrite is the usual root cause.

Example fix

// before
const content = await safeReadFile(this.persistPath, 1024 * 1024);

// after
const st = await fs.stat(this.persistPath);
if (st.size > 1024 * 1024) {
  await fs.rename(this.persistPath, `${this.persistPath}.bak-${Date.now()}`);
  // start from a fresh state file
}
const content = await safeReadFile(this.persistPath, 1024 * 1024);
Defensive patterns

Strategy: validation

Validate before calling

const st = await fs.stat(filePath);
if (st.size > limit) {
  // rotate or truncate before reading
  await fs.rename(filePath, `${filePath}.oversize-${Date.now()}`);
}

Type guard

async function isReadableSize(filePath: string, max: number): Promise<boolean> {
  const st = await fs.stat(filePath);
  return st.size <= max;
}

Try / catch

try {
  content = await safeReadFile(p, max);
} catch (e) {
  if (/^File too large/.test((e as Error).message)) { /* rotate + retry once */ }
  else throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them — this error's family across 46 libraries.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/fe87d58f5c91f034. Report an issue: GitHub.