[Bug]: helia graph walkers end the walk cleanly when a block load fails
- Dominant language
- TypeScript
- Stars
- 1
- Forks
- 0
- Avg merge
- 5d 21h
- Merged PRs (30d)
- 1
Description
**Description:** `@helia/utils` `AbstractGraphWalker.walk` runs block loads as queue jobs. When a load fails, the job's rejection is routed via `queue.add(...).catch(err => gen.throw(err))`, but the queue going idle can end the generator first — the consumer sees a clean end of stream, and the `gen.throw` on the finished generator surfaces the error as an unhandled rejection instead. The race goes both ways: sometimes the error propagates, sometimes the walk truncates silently. Any CAR assembled through these walkers (`@helia/car` export, `@helia/verified-fetch` CAR responses) can under-represent the DAG with no error.
**Steps to Reproduce:** load the pinned 21-block CAR (`test/commp-piece-cid-regression.test.ts`) into a `MemoryBlockstore`, delete one mid leaf, export via `@helia/car` with `SubgraphExporter` + `depthFirstWalker` and an exact block filter, drain the stream.
**Expected:** the export rejects with the load error.
**Actual:** the stream ends at 525,472 of 5,010,728 bytes with no error; `NotFoundError` fires later as an unhandled rejection.
**Environment:** `@helia/utils` 2.5.2, `@helia/car` 5.4.2, Node 26.
**Additional Context:** no exposure in current code — `ipfs2foc-core/car-export` drives its own traversal, so a failed load rejects the export deterministically. Tracked so the constraint stays visible (nothing in the commitment path may return to the upstream walkers until this is fixed upstream) and so the upstream report can lift this repro. The `unhandledRejection` orphan guard in `src/verified-fetch.ts` absorbs this same leak on the fallback path.
Contributor guide
Assessment
This issue has not been assessed yet.