bee index runs share w<i>/ and kill each other's workersindex/fork.js:77:A9-85 names the worker lanes w<i>/ under one be/ and :199
sweepStale clears them before spawning, so two concurrent runs on one repo
reproducibly print bee: index worker 0 failed (Error: cannot commit the
index), its files are re-indexed here; with different --fork n the stripe
residues differ and a fold can accept a foreign stripe as its own. io.reap
at :199 is uncaught, so one failed reap throws out of scan with children
unreaped and no marks. index/lindex.js:377:PS foldWork swallows a fold failure
(catch (e) { continue; }) AFTER fork.js:206 counted the stripe done, so the
marks land over missing rows. Found in the 2026-09-18 index review.
Name the worker dirs by pid (w<pid>-<i>) or take an O_EXCL lock in be/;
wrap the reap; make fold report failure back so the stripe joins rerun.
The dir is named by the PARENT's pid, w<pid>-<i>: a lock in
be/ would serialize two runs that have no reason to wait
for each other, and the pid needs no new runtime leaf. The
pid is read ONCE at module load, so a forked child inherits
it and names the dir its parent will fold.
sweepStale now sweeps only the dirs whose run is gone,
read off /proc/<pid> the way cpus() reads /sys; where
/proc is absent nothing is swept, which wastes a dir and
never takes a live worker's lane.
A fold failure cannot be injected at the lindex level: read
mode abc.index opens a missing dir, an empty dir and a
dir that is a plain FILE alike, all with count == 0. So
the swallow in foldWork is simply gone and the rerun is
covered through the fork.run callback instead.
A garbage run file in a worker dir opens as count == 1
and would be merged as rows — silent corruption, no throw.
Out of this ticket's scope; worth a ticket of its own.