zincsearch/zincsearch · error · errors.Error
runtime_exception
runtime_exception
Error message
second shard not found
What it means
GetWriter resolves a shard by numeric ID: if no explicit shardID is passed, it falls back to GetLatestShardID(). The error is thrown when the resolved shard id is out of range (>= shard count or negative), so no second shard can be located for the write/dual-write path. It surfaces from callers like CheckShards, GetWriters and WriteToShard(Rollback).
Source
Thrown at pkg/core/index_shards.go:161
s.root.lock.Unlock()
// store update
if err := storeIndex(s.root); err != nil {
return err
}
return s.openWriter(s.GetLatestShardID())
}
// GetWriter return the newest shard writer or special shard writer
func (s *IndexShard) GetWriter(shardID ...int64) (*bluge.Writer, error) {
var id int64
if len(shardID) == 1 {
id = shardID[0]
} else {
id = s.GetLatestShardID()
}
if id >= s.GetShardNum() || id < 0 {
return nil, errors.New(errors.ErrorTypeRuntimeException, "second shard not found")
}
s.lock.RLock()
secondShard := s.shards[id]
s.lock.RUnlock()
secondShard.lock.RLock()
w := secondShard.writer
secondShard.lock.RUnlock()
if w != nil {
return w, nil
}
// open writer
if err := s.openWriter(id); err != nil {
return nil, err
}
// check WALView on GitHub (pinned to dd2f8afd65)
Solutions
- Check the shardID argument you pass to GetWriter/WriteToShard; it must satisfy 0 <= id < index.GetShardNum().
- Re-run CheckShards to compare the on-disk shard count with the index metadata and repair mismatches (recreate missing shards or fix ShardNum).
- If GetLatestShardID() is the source, reinitialize the index or fix the metadata so latest shard ID is in range.
- Restore consistent index state from a good snapshot rather than manually editing shard files.
- Catch the error at the write path and fall back to shard id 0 or recreate the index if data integrity allows.
Example fix
// before
w, err := idx.GetWriter(7) // only 4 shards exist
// after
if shardID < 0 || shardID >= idx.GetShardNum() {
return fmt.Errorf("shard %d out of range (0..%d)", shardID, idx.GetShardNum()-1)
}
w, err := idx.GetWriter(shardID) Defensive patterns
Strategy: validation
Validate before calling
func safeShardID(idx *core.Index, id uint64) bool {
return id < uint64(idx.GetShardNum())
}
// call only if safeShardID(idx, shardID) before GetWriter(shardID) Type guard
func shardInRange(id int, shardNum int) bool { return id >= 0 && id < shardNum } Try / catch
w, err := idx.GetWriter(shardID)
if err != nil && strings.Contains(err.Error(), "second shard not found") {
// repair index state or fall back to a valid shard
w, err = idx.GetWriter(0)
} Prevention
- Never pass hand-picked shard IDs; omit the argument to use GetLatestShardID().
- After restoring/copying index data, always run CheckShards to reconcile shard count with metadata.
- Do not manually edit ShardNum in metadata files.
- Monitor concurrent shard resize/rebuild operations against active writers.
When it happens
Trigger: Calling GetWriter/GetWriters/WriteToShard with an explicit shardID that does not exist (id >= GetShardNum() or id < 0), or GetLatestShardID() returning a stale/invalid id (e.g. index metadata says fewer shards than actually exist after a corrupted or partial shard load).
Common situations: Manually deleting shard directories or restoring index data from a backup that mismatches metadata; passing a shard id copied from a different index; concurrent shard-resize operations racing with writers; importing an index whose ShardNum in metadata was edited by hand.
Related errors
AI-assisted analysis of zincsearch/zincsearch@dd2f8afd65 (2026-09-03).
Data as JSON: /api/errors/e9687415f25037eb.
Report an issue: GitHub.