[Detail Bug] Parser v2: Empty module-def IDs leak into allocator/argument indexes
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 4
- Forks
- 0
- Avg merge
- 15h 38m
- Merged PRs (30d)
- 37
Description
Detail Bug Report
Introduced in 12d59c28aed1f86872a3abd2ffc9285eac62c8e5 by @kewde on Jun 28, 2026
Summary
- Context:
ApplicationIndexerbuilds lookup tables (module_defs,allocators,arg_alloc,parameter_refs, …) from anApplicationProgramso downstream code indynamic.py,encode.py, andEvalContext(parser_v2) can do id-keyed lookups by module-def id. - Bug: In
_index_module_def, theif md.id:guard that skips empty/None-id module defs is applied tomodule_defsonly. The two sibling registrations —allocatorsandarg_alloc— usemd.idas the dict key with no such guard, so an empty-idModuleDefthat carries anallocatorsorargumentsblock is registered under the""key in those dicts even though it was deliberately dropped frommodule_defs. - Actual vs. expected: Expected: empty-id module defs are not registered anywhere (as documented by
test_module_def_with_empty_id_is_not_registered). Actual:module_defsomits them, butallocators[""]/arg_alloc[""]are created when the module def has allocators/arguments. - Impact: Inconsistent index state and a test gap. The leaked
""entries are currently not reachable by production read paths (allocation is gated bymodule_defspresence), but this will surface as soon as any code iterates or consumesallocators/arg_allocby module-def id without re-checkingmodule_defs.
Code with Bug
def _index_module_def(self, md: ModuleDef) -> None:
if md.id: # guard applied here (line 124)
self.module_defs[md.id] = md
...
if md.static.allocators is not None:
self.allocators[md.id] = { # <-- BUG 🔴 no `md.id` guard; writes `""` key
a.id: Allocator(id=a.id, start=a.start, max_inclusive=a.max_inclusive)
for a in md.static.allocators.allocator
}
if md.arguments is not None:
self.arg_alloc[md.id] = { # <-- BUG 🔴 no `md.id` guard; writes `""` key
a.id: (a.allocates if a.allocates is not None else 1, a.alignment.value)
for a in md.arguments.argument
}
if md.sub_module_defs is not None:
for sub in md.sub_module_defs.module_def:
self._index_module_def(sub) # same gap reached recursively for empty-id sub-module defs
Explanation
- Empty module-def IDs are schema-legal, and
ApplicationIndexerintentionally skips them viaif md.id:when populatingmodule_defs. - The same contract is not applied to
allocatorsandarg_alloc, so an empty-idModuleDefwith allocators/arguments populates those dicts under the""key. - This is demonstrable by extending the existing empty-id test to include allocators/arguments:
idx.module_defs == {}passes, butidx.allocatorsandidx.arg_alloccontain"".
Codebase Inconsistency
dynamic.pyonly createsModuleNodewhenref_idis present inidx.module_defs, andencode.pyerrors on unknown module-def IDs. This gating makes the""entries dead state today, but it also highlights the intended invariant: allocation data should be keyed only by registered module-def IDs.
Recommended Fix
- Apply the same
if md.id:guard to allocator/argument indexing (or fold all per-mdregistrations into a singleif md.id:block), and extendtest_module_def_with_empty_id_is_not_registeredto also assertidx.allocators == {}andidx.arg_alloc == {}.
History
This bug was introduced in commit 12d59c28. The commit "feat: add allocator support" extended _index_module_def with two new md.id-keyed registrations (allocators and arg_alloc) but added them outside the pre-existing if md.id: guard. A later commit (1b84e21) reformatted via ruff format without logic changes.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at ApplicationIndexer._index_module_def and the existing test_module_def_with_empty_id_is_not_registered test. Cover empty-id module definitions with allocators and arguments, then run the relevant parser_v2 tests; done means module_defs, allocators, and arg_alloc all omit the empty ID, including recursively indexed sub-module definitions.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 90/100