cayleygraph/cayley · error
cannot decode indexes: %v
Error message
cannot decode indexes: %v
What it means
readIndexesMeta reads the stored index metadata blob from the KV bucket and unmarshals it into []QuadIndex. If the stored bytes are not valid JSON or do not match the QuadIndex schema, the error is wrapped as "cannot decode indexes". A non-nil but empty list falls back to legacyQuadIndexes instead.
Source
Thrown at graph/kv/indexing.go:184
// readIndexesMeta read metadata about current indexes from the KV database.
// If no indexes are set, it returns a list of legacy indexes to preserve backward compatibility.
func (qs *QuadStore) readIndexesMeta(ctx context.Context) ([]QuadIndex, error) {
tx, err := qs.db.Tx(ctx, false)
if err != nil {
return nil, err
}
defer tx.Close()
tx = wrapTx(tx)
val, err := tx.Get(ctx, keyMetaIndexes)
if err == kv.ErrNotFound {
return legacyQuadIndexes, nil
} else if err != nil {
return nil, err
}
var out []QuadIndex
if err := json.Unmarshal(val, &out); err != nil {
return nil, fmt.Errorf("cannot decode indexes: %v", err)
} else if len(out) == 0 {
return legacyQuadIndexes, nil
}
return out, nil
}
func (qs *QuadStore) resolveValDeltas(ctx context.Context, tx kv.Tx, deltas []graphlog.NodeUpdate, fnc func(i int, id uint64)) error {
inds := make([]int, 0, len(deltas))
keys := make([]kv.Key, 0, len(deltas))
for i, d := range deltas {
if iri, ok := d.Val.(quad.IRI); ok {
if x, ok := qs.valueLRU.Get(string(iri)); ok {
fnc(i, x.(uint64))
continue
}
} else if d.Val == nil {
fnc(i, 0)
continueView on GitHub (pinned to 81dcd7d73e)
Solutions
- Back up, then reindex the store (delete the index metadata / re-run index building) so valid metadata is regenerated.
- Check the store was created by a compatible Cayley version; migrate via export/import if the format changed.
- Inspect the meta bucket value for the indexes key to confirm whether it is truncated or corrupt.
- If the directory is disposable, remove it and let the store initialize fresh with legacy indexes.
Example fix
// before: corrupt meta value
indexes_meta = "{\"wip\"" // truncated
// after: rebuild
// cayley dump --backup.db ... / cayley init on a fresh dir, then cayley load Defensive patterns
Strategy: retry
Validate before calling
// sanity-check stored metadata at startup
var probe []kv.QuadIndex
if err := json.Unmarshal(val, &probe); err != nil || len(probe) == 0 {
log.Println("index metadata invalid; reindexing recommended")
} Try / catch
out, err := qs.Open(path)
if err != nil && strings.Contains(err.Error(), "cannot decode indexes") {
return reindexStore(path) // backup, rebuild indexes, reopen
} Prevention
- Never edit database files by hand.
- Shut the store down cleanly; avoid killing the process mid-write.
- Keep backups of the data directory; migrate formats via export/import across Cayley versions.
When it happens
Trigger: Opening an existing kv-backed QuadStore (New -> readIndexesMeta) whose meta bucket contains a corrupted, truncated, or schema-incompatible indexes JSON value.
Common situations: Data directory written by an older Cayley version with a different index metadata format; disk corruption or an interrupted write leaving partial JSON; manually editing the database files.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- varint: overflow
- ErrNoBucket
- ErrEmptyPath
- kv: data version is out of date. Run cayleyupgrade for your
- could not parse config file %q: %v
AI-assisted analysis of cayleygraph/cayley@81dcd7d73e (2026-09-06).
Data as JSON: /api/errors/120fefb05f851221.
Report an issue: GitHub.