Skip to content

TypeScript: functions imported from node: built-ins resolve to same-named project functions #2491

Closed

Description

@Ancienttwo

What happens

In TypeScript, a bare call to a function that is imported by name from a Node built-in module links to an unrelated project function with the same name. The import binding is ignored.

Minimal repository (CodeGraph 1.6.1, codegraph init):

// src/policy.ts
export function resolve(input: string): string { return `policy:${input}`; }
export function relative(a: string, b: string): string { return `${a}->${b}`; }
// src/io.ts
export function existsSync(path: string): boolean { return path.length > 0; }
// src/paths.ts
import { resolve, relative } from 'node:path';
import { existsSync } from 'node:fs';

export function toAbsolute(root: string, file: string): string { return resolve(root, file); }
export function toRelative(root: string, file: string): string { return relative(root, file); }
export function present(file: string): boolean { return existsSync(file); }

calls edges in the index:

toAbsolute (src/paths.ts) -> resolve (src/policy.ts)
toRelative (src/paths.ts) -> relative (src/policy.ts)
present (src/paths.ts) -> existsSync (src/io.ts)

src/paths.ts does not import src/policy.ts or src/io.ts. All three callees are node:path / node:fs functions.

Impact

On a real TypeScript repository (about 1,100 files) the same shape appears for resolve, relative, existsSync, readFileSync and unlinkSync. The project functions with those names collect many unrelated callers, so callers, impact and call-path answers for them are wrong. A tool that uses direct calls edges as proof of a call accepts these false edges.

Expected

When the callee identifier is bound by an import from a module that is not part of the project (a node: built-in, a bare built-in such as 'path' or 'fs', or an external package), the call does not resolve to a project symbol by name. It stays unresolved, or it links to an external placeholder. Calls whose binding resolves to a project file still resolve normally.

Related but different: #1987 (built-in methods on untyped receivers) and #1566 (Map.get/set/has). This case is a bare function call with an explicit import binding.

Activity

  1. danusha2345 commented on Oct 15, 2026

    @danusha2345
    Contributor

    Thanks for the precise reproduction. I rebuilt it as given (the three files, codegraph init -y .) against current main (c71a3d0) and against the v1.6.2 build: there is no calls edge from toAbsolute, toRelative or present to src/policy.ts or src/io.ts — the three calls stay unresolved, as they should.

    The report is against 1.6.1. #2120, released in v1.6.2 (2026-10-03), added the rule you describe to the name matcher: a bare name bound by an import from outside the repository (a node: built-in, a bare built-in, a package the importing file's package.json declares) never resolves to a project symbol by name.

    Could you re-check on 1.6.2? If the 1,100-file repository still shows one of these edges there, the import line of a file whose resolve or existsSync call still links to the project's own would pin down what the rule misses.

  2. colbymchenry commented on Oct 22, 2026

    @colbymchenry
    Owner

    Thanks for the clear reproduction. Your exact case stopped linking to project functions in v1.6.2 (#2120). That covers named imports from node:path and node:fs, bare 'fs'/'path', and require('node:…').

    Two related gaps are fixed on main and ship in the next release:

    While checking, we found the same wrong link still happened when the built-in is loaded with a dynamic import, like const { createServer } = await import('node:http'). #2788 fixes that and is merged to main.

    If your repository still shows such an edge after upgrading, please share the import line of the affected file so we can see what's left.

  3. added a commit that references this issue on Oct 22, 2026
    7180fd0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions