Relative JS imports with a query string (`./foo.js?v=123`) are not resolved

Closed Beginner friendly
#4,860 3 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

@AdapaRohith is already working on this.

Since Oct 29, 2026.

  • #4869 by @mirzasnowy — closed without merging
  • #4876 by @Jitendarmahara — closed without merging

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
76/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Domain
backend, devtools

Research direction

Read extractors/resolution.py around _resolve_js_module_path (lines 855–856) and compare its handling with extractors/markdown.py around line 289. Check how relative JavaScript and TypeScript specifiers with query strings or fragments are resolved, then run the relevant resolution tests. Done means ./foo.js?v=123 resolves to ./foo.js without creating a phantom node; the issue does not name a specific test file.

Written by the indexing model from the issue text.

Description

Version: graphify 0.9.93 (graphifyy), extract --code-only, GRAPHIFY_BACKEND=none

Description
ES module imports that include a cache-busting query string are not resolved to the target file:

import { foo } from './lib/foo.js?v=134';

Instead of an imports_from edge to lib/foo.js, graphify creates a phantom node (e.g. ref_foo_js_v_134) and the real file gets no inbound edge. Symbol imports and cross-file calls are lost as well, since they depend on the module resolving.

Impact (real project, 93 JS files)

  • Phantom _v_ nodes: 96 → 0 after stripping the suffix
  • Inbound imports_from edges for the most-used module: 0 → 29
  • Symbol imports: 30 → 413
  • About 400 cross-file calls edges recovered

Root cause
extractors/resolution.py, lines 855-856 (_resolve_js_module_path): relative specifiers are resolved with start_dir / raw without stripping the ?query / #fragment part. The Markdown extractor already strips it (extractors/markdown.py:289), so applying the same normalization to relative JS/TS specifiers should fix it.

Also present on v8 (default branch) as of 0a8cd4e1e342235fe53e881fb5d591bf0460071f (resolution.py lines 868-869).

Current workaround
Copy the tree to a temp dir, strip the suffix with sed -E 's/(\.js)\?v=[0-9]+/\1/g', and extract from the copy.

Expected behavior
./foo.js?v=123 resolves to ./foo.js, as browsers and bundlers do for module resolution.

Related: #2849 lists one ../styles.css?url import under "Resource-query import is unresolved". It looks like the same root cause.

Dominant language
Python
Stars
124k
Forks
11.9k
Avg merge
1h 26m
Merged PRs (30d)
2

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from Graphify-Labs/graphify

All issues in Graphify-Labs/graphify

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.