abhigyanpatwari/GitNexus · error

${filename} exceeds ${MAX_REPO_CONTROL_FILE_BYTES} bytes

Error message

${filename} exceeds ${MAX_REPO_CONTROL_FILE_BYTES} bytes

What it means

readRepoControlFile enforces a maximum size (MAX_REPO_CONTROL_FILE_BYTES) on control files both before and during reading; the pre-open lstat check throws this error when the file is already too large. This prevents pathological memory/DoS exposure from an oversized or maliciously grown config file.

Source

Thrown at gitnexus/src/config/repo-control-file.ts:25

export async function readRepoControlFile(
  repoRoot: string,
  filename: string,
): Promise<string | null> {
  const requestedRoot = path.resolve(repoRoot);
  const requested = path.resolve(requestedRoot, filename);
  const relative = path.relative(requestedRoot, requested);
  if (relative.startsWith('..') || path.isAbsolute(relative)) {
    throw new Error(`${filename} resolves outside the repository root`);
  }

  try {
    const canonicalRoot = fs.realpathSync(requestedRoot);
    const beforeOpen = fs.lstatSync(requested);
    if (beforeOpen.isSymbolicLink()) throw new Error(`${filename} must not be a symbolic link`);
    if (!beforeOpen.isFile()) throw new Error(`${filename} must be a regular file`);
    if (beforeOpen.nlink !== 1) throw new Error(`${filename} must not be a hard link`);
    if (beforeOpen.size > MAX_REPO_CONTROL_FILE_BYTES) {
      throw new Error(`${filename} exceeds ${MAX_REPO_CONTROL_FILE_BYTES} bytes`);
    }
    return await new Promise<string>((resolve, reject) => {
      const stream = fs.createReadStream(requested, {
        flags: 'r',
        start: 0,
        end: MAX_REPO_CONTROL_FILE_BYTES,
        autoClose: true,
      });
      const chunks: Buffer[] = [];
      let totalBytes = 0;
      let validated = false;
      let settled = false;

      const finish = (value: string): void => {
        if (settled) return;
        settled = true;
        resolve(value);
      };

View on GitHub (pinned to 52924ef12c)

Solutions

  1. Inspect `fs.lstatSync(path).size` and compare against MAX_REPO_CONTROL_FILE_BYTES; trim the file to the allowed size.
  2. Remove accidental content (logs, duplicates) from the control file, keeping only the intended config.
  3. Restore the file from version control (`git checkout -- <file>`).
  4. Regenerate the control file with the tooling that originally created it.

Example fix

// before: oversized .gitnexusrc (e.g. 10 MB of appended logs)
cat debug.log >> .gitnexusrc
// after: small, hand-maintained file
printf 'mode: strict\n' > .gitnexusrc
Defensive patterns

Strategy: validation

Validate before calling

import fs from 'node:fs';
const st = fs.lstatSync(controlFilePath);
const MAX = 64 * 1024; // match MAX_REPO_CONTROL_FILE_BYTES
if (st.size > MAX) {
  throw new Error(`${controlFilePath} is ${st.size} bytes; cap is ${MAX}`);
}

Try / catch

try {
  await readRepoControlFile(root, filename);
} catch (err) {
  if ((err as Error).message.includes('exceeds') && err.message.includes('bytes')) {
    // trim or regenerate the config below the cap, then retry
  } else throw err;
}

Prevention

When it happens

Trigger: Calling readRepoControlFile when fs.lstatSync(requested).size exceeds MAX_REPO_CONTROL_FILE_BYTES — i.e. the control file on disk is larger than the configured byte cap.

Common situations: A log or output file was accidentally redirected into the config path; a generated config ballooned after a bad script concatenated repeatedly; someone replaced the config with a large binary blob.

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 abhigyanpatwari/GitNexus@52924ef12c (2026-09-01). Data as JSON: /api/errors/c775e15b95d43e51. Report an issue: GitHub.