cayleygraph/cayley · error
cannot get horizon value: %v
Error message
cannot get horizon value: %v
What it means
getMetaIntTx fetches a 8-byte little-endian integer from the meta bucket within a transaction. ErrNotFound is normal (treated as 0), but any other storage error is wrapped as "cannot get horizon value". The name references the horizon/size counters kept in the meta bucket, despite the generic key parameter.
Source
Thrown at graph/kv/indexing.go:240
continue
}
ind := inds[i]
id, _ := binary.Uvarint(b)
d := &deltas[ind]
if iri, ok := d.Val.(quad.IRI); ok && id != 0 {
qs.valueLRU.Put(string(iri), uint64(id))
}
fnc(ind, uint64(id))
}
return nil
}
func (qs *QuadStore) getMetaIntTx(ctx context.Context, tx kv.Tx, key string) (int64, error) {
val, err := tx.Get(ctx, metaBucket.AppendBytes([]byte(key)))
if err == kv.ErrNotFound {
return 0, err
} else if err != nil {
return 0, fmt.Errorf("cannot get horizon value: %v", err)
}
return int64(binary.LittleEndian.Uint64(val)), nil
}
func (qs *QuadStore) incMetaInt(ctx context.Context, tx kv.Tx, key string, n int64) (int64, error) {
if n == 0 {
return 0, nil
}
v, err := qs.getMetaIntTx(ctx, tx, key)
if err != nil && err != kv.ErrNotFound {
return 0, fmt.Errorf("cannot get %s: %v", key, err)
}
start := v
v += n
buf := make([]byte, 8) // bolt needs all slices available on Commit
binary.LittleEndian.PutUint64(buf, uint64(v))
View on GitHub (pinned to 81dcd7d73e)
Solutions
- Inspect the wrapped inner error (%v) to identify the backend failure and fix that root cause.
- Verify the database file is accessible and not locked by another process or opened with conflicting options.
- Check disk health/space and file permissions on the KV database.
- Restart the process and reopen the store; if corruption persists, restore from backup and reindex.
Example fix
// before: store closed while goroutines still write qs.Close(); qs.incSize(ctx, 1) // cannot get horizon value: tx on closed db // after // ensure all writers finish before Close, or reopen the store before writing qs2, err := kv.New(...); qs2.incSize(ctx, 1)
Defensive patterns
Strategy: retry
Validate before calling
if qs == nil || closed {
return fmt.Errorf("store must be open before meta operations")
} Try / catch
n, err := qs.incSize(ctx, 1)
if err != nil {
if errors.Is(err, kv.ErrNotFound) {
n = 0 // first increment
} else if strings.Contains(err.Error(), "cannot get") {
// inspect wrapped backend error, reopen store or fail fast
return reopenAndRetry()
}
} Prevention
- Close the store only after all writers finish.
- Monitor disk health and space on KV database volumes.
- Do not open the same database from multiple processes with incompatible locking.
When it happens
Trigger: Any kv transaction Get on a meta key failing with a storage-level error (I/O error, closed DB, bolt/leveldb failure) during incMetaInt-driven writes such as size increments or ID generation.
Common situations: Underlying KV database file locked or corrupted; disk I/O errors; transaction used after the store was closed; backend-specific failures surfaced through kv.Tx.Get.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- cannot get %s: %v
- cannot inc %s: %v
- ErrNoBucket
- ErrEmptyPath
- kv: data version is out of date. Run cayleyupgrade for your
AI-assisted analysis of cayleygraph/cayley@81dcd7d73e (2026-09-06).
Data as JSON: /api/errors/6b81b084560afc0e.
Report an issue: GitHub.