{"record":{"id":"fbeefb17b44c60a8","repo":"abhigyanpatwari/GitNexus","slug":"options-languagelabel-package-siblings-skippi","errorCode":null,"errorMessage":"[${options.languageLabel}-package-siblings] skipping package with ${bucket.moduleScopes.length} files (cap=${MAX_PACKAGE_FILES}); same-package implicit visibility disabled for this package","messagePattern":"\\[(.+?)-package-siblings\\] skipping package with (.+?) files \\(cap=(.+?)\\); same-package implicit visibility disabled for this package","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"gitnexus/src/core/ingestion/languages/jvm/package-siblings.ts","lineNumber":101,"sourceCode":"    // A file whose package cannot be proven may shadow a wildcard-imported\n    // type in any package. Conservatively disable wildcard attribution for the\n    // language workspace while leaving explicit/FQN imports available.\n    if (unknownPackageFiles.size > 0) {\n      for (const parsed of parsedFiles) incompleteFiles.add(parsed.filePath);\n      logger.warn(\n        `[${options.languageLabel}-package-siblings] ${unknownPackageFiles.size} file(s) lacked reliable package facts; wildcard attribution disabled for this language workspace`,\n      );\n    }\n\n    const augmentations = indexes.bindingAugmentations as Map<ScopeId, Map<string, BindingRef[]>>;\n    const maxInjectedSiblings = getMaxInjectedSiblings();\n    let truncatedFiles = 0;\n\n    for (const bucket of buckets.values()) {\n      if (bucket.moduleScopes.length < 2) continue;\n      if (bucket.moduleScopes.length > MAX_PACKAGE_FILES) {\n        for (const parsed of bucket.parsed) incompleteFiles.add(parsed.filePath);\n        logger.warn(\n          `[${options.languageLabel}-package-siblings] skipping package with ${bucket.moduleScopes.length} files (cap=${MAX_PACKAGE_FILES}); same-package implicit visibility disabled for this package`,\n        );\n        continue;\n      }\n\n      const classDefs: { def: BindingRef['def']; filePath: string }[] = [];\n      for (const parsed of bucket.parsed) {\n        const moduleScopeId = parsed.scopes.find((scope) => scope.kind === 'Module')?.id;\n        for (const scope of parsed.scopes) {\n          if (scope.kind !== 'Class' || scope.parent !== moduleScopeId) continue;\n          const def = scope.ownedDefs.find((candidate) => isClassLike(candidate.type));\n          if (def !== undefined) classDefs.push({ def, filePath: parsed.filePath });\n        }\n      }\n\n      // Per-bucket lookups: the per-file loop below is O(files²) over these,\n      // so split each path into segments once here instead of re-splitting it\n      // on every pairwise proximity comparison, and address siblings by path","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/aac7515d2a8c50a1f8f923c6fb77218b333560d6/gitnexus/src/core/ingestion/languages/jvm/package-siblings.ts#L83-L119","documentation":"GitNexus caps same-package sibling processing at MAX_PACKAGE_FILES = 500 files per package to bound ingestion cost. When a package bucket holds more than 500 module scopes, the whole bucket is skipped: no same-package implicit visibility is injected, every file in it is marked visibility-incomplete, and this warning is emitted. GITNEXUS_MAX_INJECTED_SIBLINGS only bounds injection within processed packages — it does not lift this skip.","triggerScenarios":"A Java/Kotlin workspace where a single declared package (or the default package) spans more than 500 parsed files, so bucket.moduleScopes.length > 500 and the loop continues past the bucket.","commonSituations":"Code generators emitting thousands of classes into one package, legacy code in the default package, massive flat util packages, or vendored SDKs sharing one package namespace.","solutions":["Identify the oversized package and split it into sub-packages in the source","Exclude generated/vendored members of that package via .gitnexusignore and re-run analyze","Accept degraded same-package/wildcard visibility for that package — explicit imports still resolve","Do not bother raising GITNEXUS_MAX_INJECTED_SIBLINGS: the 500-file package cap is hard-coded and independent"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Pre-flight: count parsed files per package; flag anything over the 500-file cap\nconst byPkg = new Map();\nfor (const f of javaFiles) {\n  const m = readFileSync(f, 'utf8').match(/^package\\s+([\\w.]+);/m);\n  const pkg = m ? m[1] : '(default)';\n  byPkg.set(pkg, (byPkg.get(pkg) ?? 0) + 1);\n}\nfor (const [pkg, n] of byPkg) if (n > 500) console.error(`package ${pkg} has ${n} files — same-package visibility will be skipped`);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep packages under a few hundred files; split generator output into sub-packages","Exclude bulk-generated trees from analysis with .gitnexusignore","Treat any isVisibilityIncomplete answers for huge packages as low-trust in downstream tooling"],"tags":["jvm","java","kotlin","ingestion","limits","package-visibility"],"backgroundTag":"analysis-results-truncated","analyzedSha":"aac7515d2a8c50a1f8f923c6fb77218b333560d6","analyzedAt":"2026-08-20T23:29:22.980Z","contentChangedAt":"2026-08-20T23:29:22.980Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}