{"record":{"id":"38b94a4e30a9bfcf","repo":"abhigyanpatwari/GitNexus","slug":"cobol-copy-expander-max-expansion-depth-maxde","errorCode":null,"errorMessage":"[cobol-copy-expander] Max expansion depth (${maxDepth}) reached for COPY ${cs.target} in ${srcPath}. Skipping expansion.","messagePattern":"\\[cobol-copy-expander\\] Max expansion depth \\((.+?)\\) reached for COPY (.+?) in (.+?)\\. Skipping expansion\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"gitnexus/src/core/ingestion/cobol/cobol-copy-expander.ts","lineNumber":468,"sourceCode":"      if (resolvedPath === null) {\n        continue;\n      }\n\n      // Cycle detection\n      if (visited.has(resolvedPath)) {\n        if (!warnedCircular.has(resolvedPath)) {\n          warnedCircular.add(resolvedPath);\n          logger.warn(\n            `[cobol-copy-expander] Circular COPY detected: ${cs.target} (${resolvedPath}) ` +\n              `includes itself. Skipping expansion.`,\n          );\n        }\n        continue;\n      }\n\n      // Max depth exceeded — keep unexpanded\n      if (depth >= maxDepth) {\n        logger.warn(\n          `[cobol-copy-expander] Max expansion depth (${maxDepth}) reached for ` +\n            `COPY ${cs.target} in ${srcPath}. Skipping expansion.`,\n        );\n        continue;\n      }\n\n      // Guard against exponential breadth amplification (N copybooks each with N COPYs)\n      if (++totalExpansions > MAX_TOTAL_EXPANSIONS) {\n        if (!warnedCircular.has('__max_total__')) {\n          warnedCircular.add('__max_total__');\n          logger.warn(\n            `[cobol-copy-expander] Max total expansions (${MAX_TOTAL_EXPANSIONS}) reached ` +\n              `in ${srcPath}. Skipping further expansions.`,\n          );\n        }\n        continue;\n      }\n","sourceCodeStart":450,"sourceCodeEnd":486,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/aac7515d2a8c50a1f8f923c6fb77218b333560d6/gitnexus/src/core/ingestion/cobol/cobol-copy-expander.ts#L450-L486","documentation":"COPY nesting exceeded the maximum expansion depth (DEFAULT_MAX_DEPTH = 10, the expander's maxDepth parameter). COPYs nested deeper than 10 levels are left unexpanded with original lines kept, so the preprocessed output can still contain unresolved COPY statements.","triggerScenarios":"A copybook chain longer than 10 levels deep (C1 COPYs C2, C2 COPYs C3, ... C11), common in layered mainframe include hierarchies.","commonSituations":"Deeply layered copybook trees built up over decades; hierarchical site-standard includes that fan in at every level.","solutions":["Flatten the copybook hierarchy to fewer than 10 nesting levels","When invoking the expander programmatically, pass a higher maxDepth sized to the real chain length","Accept partial expansion and check the preprocessed output for remaining COPY statements"],"exampleFix":"// before — default depth\nexpandCopyStatements(source, { maxDepth: 10 });\n\n// after — chain is 14 levels deep\nexpandCopyStatements(source, { maxDepth: 20 });","handlingStrategy":"validation","validationCode":"// Pre-flight: measure COPY nesting depth, then size maxDepth to it\nfunction copyChainDepth(source: string, resolve: (t: string) => string | null, seen = new Set<string>()): number {\n  const copies = [...source.matchAll(/\\bCOPY\\s+([\\w-]+)/gi)].map((m) => m[1]);\n  let max = 0;\n  for (const target of copies) {\n    if (seen.has(target)) continue; // cycle guard\n    const content = resolve(target);\n    if (content === null) continue;\n    max = Math.max(max, 1 + copyChainDepth(content, resolve, new Set(seen).add(target)));\n  }\n  return max;\n}\nconst depth = copyChainDepth(mainSource, resolveCopybook);\nexpandCopyStatements(mainSource, { maxDepth: Math.max(10, depth + 1) });","typeGuard":"function withinCopyDepth(source: string, resolve: (t: string) => string | null, maxDepth = 10): boolean {\n  return copyChainDepth(source, resolve) <= maxDepth;\n}","tryCatchPattern":null,"preventionTips":["Keep copybook hierarchies shallow — fewer than 10 nesting levels","Measure the real chain depth before invoking the expander and pass a maxDepth sized to it","Periodically flatten include trees during mainframe modernization work"],"tags":["cobol","copybook","depth-limit","preprocessor"],"backgroundTag":"include-depth-limit","analyzedSha":"aac7515d2a8c50a1f8f923c6fb77218b333560d6","analyzedAt":"2026-08-20T23:29:22.980Z","contentChangedAt":"2026-08-20T23:29:22.980Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}