abhigyanpatwari/GitNexus · warning

[cobol-copy-expander] Max total expansions (${MAX_TOTAL_EXPA

Error message

[cobol-copy-expander] Max total expansions (${MAX_TOTAL_EXPANSIONS}) reached in ${srcPath}. Skipping further expansions.

What it means

The copybook expander counts cumulative COPY expansions per file; once the count passes MAX_TOTAL_EXPANSIONS (500) it stops expanding further COPYs, leaving them unexpanded, and warns once (warnedCircular gate keyed '__max_total__'). This bounds exponential breadth amplification: N copybooks each containing N COPYs.

Source

Thrown at gitnexus/src/core/ingestion/cobol/cobol-copy-expander.ts:479

          );
        }
        continue;
      }

      // Max depth exceeded — keep unexpanded
      if (depth >= maxDepth) {
        logger.warn(
          `[cobol-copy-expander] Max expansion depth (${maxDepth}) reached for ` +
            `COPY ${cs.target} in ${srcPath}. Skipping expansion.`,
        );
        continue;
      }

      // Guard against exponential breadth amplification (N copybooks each with N COPYs)
      if (++totalExpansions > MAX_TOTAL_EXPANSIONS) {
        if (!warnedCircular.has('__max_total__')) {
          warnedCircular.add('__max_total__');
          logger.warn(
            `[cobol-copy-expander] Max total expansions (${MAX_TOTAL_EXPANSIONS}) reached ` +
              `in ${srcPath}. Skipping further expansions.`,
          );
        }
        continue;
      }

      // Read the copybook content
      const copybookContent = readFile(resolvedPath);
      if (copybookContent === null) {
        continue;
      }

      // Apply REPLACING transformations
      const replaced = applyReplacing(copybookContent, cs.replacing);

      // Recurse into the copybook for nested COPYs
      const nestedVisited = new Set(visited);

View on GitHub (pinned to aac7515d2a)

Solutions

  1. Reduce copybook reuse breadth — deduplicate repeated COPY statements of the same member
  2. Split the oversized program into smaller members
  3. Accept partial expansion and audit remaining COPY statements in the preprocessed output

Example fix

* before — 60 copies of a 10-COPY fragment (600 total expansions)
       COPY FRAG. COPY FRAG. ... (x60)

* after — reference one expanded copy or reduce fan-out below 500 total
Defensive patterns

Strategy: validation

Validate before calling

// Pre-flight: estimate total expansions (fan-out sum per level) before running
function estimateExpansions(source: string, resolve: (t: string) => string | null, depth = 0): number {
  if (depth >= 10) return 0;
  let total = 0;
  for (const m of source.matchAll(/\bCOPY\s+([\w-]+)/gi)) {
    const content = resolve(m[1]);
    total += 1 + (content ? estimateExpansions(content, resolve, depth + 1) : 0);
  }
  return total;
}
if (estimateExpansions(src, resolveCopybook) > 500) {
  console.warn('COPY fan-out exceeds the 500-expansion budget — reduce reuse or split the member');
}

Type guard

function withinExpansionBudget(source: string, resolve: (t: string) => string | null, budget = 500): boolean {
  return estimateExpansions(source, resolve) <= budget;
}

Prevention

When it happens

Trigger: A file whose copybooks fan out — many COPY statements where each expanded copybook itself contains many more COPYs — pushing cumulative expansions past 500 even though nesting depth stays under 10.

Common situations: Heavily reused copybook libraries referenced dozens of times per program; generated COBOL that repeats COPY boilerplate; members assembled from shared fragment libraries.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@aac7515d2a (2026-08-20). Data as JSON: /api/errors/853f9f904e8fb0d4. Report an issue: GitHub.