Skip to content

[Bug]: Incremental index fails in merge stage (FtsRocksdbReducer: source postings is not BitPacked) and leaves the index unopenable #158

Description

@vchen12

Description

On a large Markdown/plain-text workspace (~20,000 files), incremental zg index runs repeatedly fail in the merge stage with ZVEC_INTERNAL_ERROR. The CLI message observed for one of these failures was:

[ZVEC_INTERNAL_ERROR] FtsRocksdbReducer: source postings is not BitPacked. field=text

After such a failure the index is left unopenable: every subsequent zg status / zg query returns Failed to open zvec collection storage (ZVEC_GREP.ENGINE.STORAGE.ZVEC_OPEN_FAILED), index.zvec is left with unfinished *.tmp directories, and the on-disk index had grown from 3.3 GB to 6.3 GB. The only recovery we found is a full zg index --rebuild, which takes about 5 hours for this corpus.

Expected: an incremental index job that fails should leave the previous index intact and queryable, and should be retryable without a full rebuild.

This is not a one-off. The daemon log on this machine records 117 ZVEC_INTERNAL_ERROR job failures between 2026-09-04 and 2026-09-14, spanning zg 0.2.1 and 0.2.2.

Three related problems found while recovering

  1. A stale in-process RocksDB lock blocks --rebuild. Running zg index --rebuild directly after the failure deletes the old storage but then fails to create the new one (create id map failed); files.zvec/idmap.0/LOG says lock hold by current process, i.e. the still-running daemon holds a lock on the already-deleted storage. Recovery requires zg server off && zg server on before --rebuild. It would help if the rebuild path released and reopened the storage itself, or if the error named the holding daemon.
  2. The daemon log never persists the error message. ~/.zvec-grep/daemon/logs/server.log records only "error_code":"ZVEC_INTERNAL_ERROR" on job.finished - no message, no stack. The FtsRocksdbReducer text above was only visible on the CLI at the time, so for scheduled or background runs the cause is unrecoverable after the fact. Please log the message (and ideally the failing field/segment) next to the code.
  3. A rebuild is neither resumable nor reported as partial. A rebuild interrupted by daemon exit (the machine slept overnight) left 674 MB written under index.zvec, but zg status then reports Coverage 0% - 0 / 20,357 files with 20,357 added pending. The written data is not reused, and nothing indicates that an earlier rebuild was interrupted.

One local modification worth disclosing: the index home is redirected out of the workspace to a local disk path, via ~/.zvec-grep/workspace-homes.json plus a small patch to dist/engine/service/root.js, because the workspace itself lives in a cloud-sync folder where RocksDB writes time out. The patch only changes where the index home resolves to; indexing and merging are untouched.

Steps to Reproduce

  1. Install zg (npm install @zvec/zvec-grep plus @zvec/zvec) and the local/potion-multilingual-128m model.
  2. Index a workspace of roughly 20,000 .md / .txt files:
    zg index -t markdown -t txt -g '!<excluded-dir>/**' --embedding local/potion-multilingual-128m
  3. Let a daily incremental run add or modify a few hundred files, then run zg index --mode server again. Repeat daily.
  4. Observe: after about 100 s the job ends with state=failed, error_code=ZVEC_INTERNAL_ERROR, and the CLI shows FtsRocksdbReducer: source postings is not BitPacked. field=text.
  5. zg status --mode server now returns Failed to open zvec collection storage; the index stays unusable until a full --rebuild.

We have not isolated a specific triggering document. The failures happen in the merge stage, not during extraction.

Version and Diagnostics

zg --version         0.2.2          (also seen on 0.2.1)
@zvec/zvec           0.7.1          (official @zvec/bindings-darwin-x64 prebuilt)
node --version       v24.13.0
sw_vers              macOS 12.7.6 (21H1320), x86_64 (Intel)
embedding            local/potion-multilingual-128m - 256 dimensions - cosine
workspace            20,357 files, type=markdown|txt, one directory excluded by glob
index size           2.8-3.3 GB when healthy; 6.3 GB after the failed merge

Logs or Error Output

Daily breakdown of job.finished events from ~/.zvec-grep/daemon/logs/server.log (paths redacted):

2026-09-09 {'ZVEC_INTERNAL_ERROR': 1, 'succeeded': 52}
2026-09-11 {'ZVEC_INTERNAL_ERROR': 1, 'ZVEC_GREP.ENGINE.STORAGE.ZVEC_OPEN_FAILED': 1, 'succeeded': 8}
2026-09-12 {'succeeded': 48, 'ZVEC_GREP.ENGINE.INDEXING.CONTENT_HASH_FAILED': 1}
2026-09-13 {'succeeded': 20, 'ZVEC_GREP.ENGINE.INDEXING.CONTENT_HASH_FAILED': 3}
2026-09-14 {'ZVEC_INTERNAL_ERROR': 1}

The 2026-09-11 pair is the corruption sequence - the internal error, after which the storage can no longer be opened:

{"timestamp":"2026-09-11T16:14:31.361Z","event":"job.finished","state":"failed","attempt":1,"error_code":"ZVEC_INTERNAL_ERROR","duration_ms":1090528}
{"timestamp":"2026-09-11T21:55:42.661Z","event":"job.finished","state":"failed","attempt":1,"error_code":"ZVEC_GREP.ENGINE.STORAGE.ZVEC_OPEN_FAILED","duration_ms":807}

Most recent occurrence (2026-09-14), showing that only the code is logged, never the message:

{"timestamp":"2026-09-14T15:04:41.023Z","event":"job.started","job_id":"d4bb4341-...","reason":"manual","attempt":1}
{"timestamp":"2026-09-14T15:06:27.037Z","event":"job.finished","job_id":"d4bb4341-...","state":"failed","attempt":1,"error_code":"ZVEC_INTERNAL_ERROR","duration_ms":106014}

Aggregate failure counts in this log (2026-09-04 to 2026-09-14, 393 failed jobs in total):

ZVEC_GREP.ENGINE.STORAGE.ZVEC_OPEN_FAILED      244   (index unopenable after a failed merge)
ZVEC_INTERNAL_ERROR                            117
ZVEC_GREP.ENGINE.DAEMON_LEASE_ACTIVE            17
ZVEC_GREP.ENGINE.LOCK.BUSY                       9
ZVEC_GREP.ENGINE.INDEXING.CONTENT_HASH_FAILED    4
ZVEC_GREP.ENGINE.INDEXING.STATUS_FAILED          2

Because the message is not logged, we can only confirm the "FtsRocksdbReducer ... not BitPacked" text for the failure of 2026-09-11T16:14Z, which was observed on the CLI. The other ZVEC_INTERNAL_ERROR entries share the code and the same merge-stage timing, but we cannot prove they are all the same defect.

Operating System

macOS 12.7.6 (Intel x86_64)

Installation Method

npm project dependency

Affected Area

Indexing or file extraction, Local server

Pre-submission Checklist

  • I checked the zvec-grep troubleshooting guide and existing issues.
  • I removed credentials, private paths, and sensitive file contents from this report.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions