{"record":{"id":"120fefb05f851221","repo":"cayleygraph/cayley","slug":"cannot-decode-indexes-v","errorCode":null,"errorMessage":"cannot decode indexes: %v","messagePattern":"cannot decode indexes: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"graph/kv/indexing.go","lineNumber":184,"sourceCode":"\n// readIndexesMeta read metadata about current indexes from the KV database.\n// If no indexes are set, it returns a list of legacy indexes to preserve backward compatibility.\nfunc (qs *QuadStore) readIndexesMeta(ctx context.Context) ([]QuadIndex, error) {\n\ttx, err := qs.db.Tx(ctx, false)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer tx.Close()\n\ttx = wrapTx(tx)\n\tval, err := tx.Get(ctx, keyMetaIndexes)\n\tif err == kv.ErrNotFound {\n\t\treturn legacyQuadIndexes, nil\n\t} else if err != nil {\n\t\treturn nil, err\n\t}\n\tvar out []QuadIndex\n\tif err := json.Unmarshal(val, &out); err != nil {\n\t\treturn nil, fmt.Errorf(\"cannot decode indexes: %v\", err)\n\t} else if len(out) == 0 {\n\t\treturn legacyQuadIndexes, nil\n\t}\n\treturn out, nil\n}\n\nfunc (qs *QuadStore) resolveValDeltas(ctx context.Context, tx kv.Tx, deltas []graphlog.NodeUpdate, fnc func(i int, id uint64)) error {\n\tinds := make([]int, 0, len(deltas))\n\tkeys := make([]kv.Key, 0, len(deltas))\n\tfor i, d := range deltas {\n\t\tif iri, ok := d.Val.(quad.IRI); ok {\n\t\t\tif x, ok := qs.valueLRU.Get(string(iri)); ok {\n\t\t\t\tfnc(i, x.(uint64))\n\t\t\t\tcontinue\n\t\t\t}\n\t\t} else if d.Val == nil {\n\t\t\tfnc(i, 0)\n\t\t\tcontinue","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/cayleygraph/cayley/blob/81dcd7d73e45136bc0d01802a8ba4685d8a533eb/graph/kv/indexing.go#L166-L202","documentation":"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.","triggerScenarios":"Opening an existing kv-backed QuadStore (New -> readIndexesMeta) whose meta bucket contains a corrupted, truncated, or schema-incompatible indexes JSON value.","commonSituations":"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.","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."],"exampleFix":"// before: corrupt meta value\nindexes_meta = \"{\\\"wip\\\"\" // truncated\n// after: rebuild\n// cayley dump --backup.db ... / cayley init on a fresh dir, then cayley load","handlingStrategy":"retry","validationCode":"// sanity-check stored metadata at startup\nvar probe []kv.QuadIndex\nif err := json.Unmarshal(val, &probe); err != nil || len(probe) == 0 {\n    log.Println(\"index metadata invalid; reindexing recommended\")\n}","typeGuard":null,"tryCatchPattern":"out, err := qs.Open(path)\nif err != nil && strings.Contains(err.Error(), \"cannot decode indexes\") {\n    return reindexStore(path) // backup, rebuild indexes, reopen\n}","preventionTips":["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."],"tags":["kv-store","json","corruption"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"81dcd7d73e45136bc0d01802a8ba4685d8a533eb","analyzedAt":"2026-09-06T06:14:12.358Z","contentChangedAt":"2026-09-06T06:14:12.358Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}