abhigyanpatwari/GitNexus · warning

go range-binding: parse timed out, skipping file

Error message

go range-binding: parse timed out, skipping file

What it means

The Go range-binding pass re-parses each file with parseSourceSafe (reusing a cached tree when available). parseSourceSafe enforces a per-parse wall-clock budget — 15 s default, GITNEXUS_PARSE_TIMEOUT_MS overrides, 0 disables — and throws ParseTimeoutError when exceeded. The pass catches that error type, warns 'go range-binding: parse timed out, skipping file', and skips the file's range bindings; other errors rethrow.

Source

Thrown at gitnexus/src/core/ingestion/languages/go/range-binding.ts:35

  for (const parsed of parsedFiles) {
    const sourceText = ctx.fileContents.get(parsed.filePath);
    if (sourceText === undefined) continue;

    const cachedTree = ctx.treeCache?.get(parsed.filePath) as
      | ReturnType<typeof parser.parse>
      | undefined;
    let tree: ReturnType<typeof parser.parse>;
    if (cachedTree !== undefined) {
      tree = cachedTree;
    } else {
      try {
        tree = parseSourceSafe(parser, sourceText, undefined, {
          bufferSize: getTreeSitterBufferSize(sourceText),
        });
      } catch (err) {
        if (err instanceof ParseTimeoutError) {
          logger.warn(
            { file: parsed.filePath },
            'go range-binding: parse timed out, skipping file',
          );
          continue;
        }
        throw err;
      }
    }
    const moduleScope = parsed.scopes.find((s) => s.kind === 'Module');
    if (moduleScope === undefined) continue;

    const scopeMap = new Map(parsed.scopes.map((s) => [s.id, s]));

    for (const rangeNode of tree.rootNode.descendantsOfType('for_statement')) {
      const rangeClause = rangeNode.namedChildren.find((c) => c.type === 'range_clause');
      if (rangeClause === undefined) continue;

      const left = rangeClause.namedChildren.find((c) => c.type === 'expression_list');

View on GitHub (pinned to aac7515d2a)

Solutions

  1. Identify the file from the warn's { file } field
  2. Exclude generated .pb.go/mock files from indexing (they are rarely worth full PDG coverage)
  3. Raise the budget with GITNEXUS_PARSE_TIMEOUT_MS, staying under the 30 s worker idle timeout
  4. Re-run on a machine with more CPU headroom
  5. Accept the skip — scope resolution still runs; only range bindings for that file are lost

Example fix

# before: default 15s budget trips on megabyte-scale .pb.go stubs
npx gitnexus analyze

# after: raise the budget below the 30s worker idle ceiling
GITNEXUS_PARSE_TIMEOUT_MS=25000 npx gitnexus analyze
Defensive patterns

Strategy: validation

Validate before calling

// prescreen: generated Go stubs are the classic timeout source
if (/\.pb\.go$|\.mock\.go$/.test(file) || (await fs.promises.stat(file)).size > 1_500_000) {
  addToFileExclusions(file);
}

Try / catch

try {
  tree = parseSourceSafe(parser, sourceText, undefined, { bufferSize: getTreeSitterBufferSize(sourceText) });
} catch (err) {
  if (err instanceof ParseTimeoutError) { skipRangeBindingsFor(file); continue; }
  throw err;
}

Prevention

When it happens

Trigger: A Go file whose parse exceeds the budget: giant generated protobuf/gRPC stubs (.pb.go files are routinely megabytes), deeply nested composite literals, or CPU-starved runners pushing normal files past 15 s.

Common situations: Indexing a repo with vendored .pb.go or mockgen output; CI containers with low CPU shares; concurrent analyze runs on one box.

Understand the failure class

Related errors


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