{"record":{"id":"e9687415f25037eb","repo":"zincsearch/zincsearch","slug":"runtime-exception","errorCode":"runtime_exception","errorMessage":"second shard not found","messagePattern":"second shard not found","errorType":"exception","errorClass":"errors.Error","httpStatus":null,"severity":"error","filePath":"pkg/core/index_shards.go","lineNumber":161,"sourceCode":"\ts.root.lock.Unlock()\n\n\t// store update\n\tif err := storeIndex(s.root); err != nil {\n\t\treturn err\n\t}\n\treturn s.openWriter(s.GetLatestShardID())\n}\n\n// GetWriter return the newest shard writer or special shard writer\nfunc (s *IndexShard) GetWriter(shardID ...int64) (*bluge.Writer, error) {\n\tvar id int64\n\tif len(shardID) == 1 {\n\t\tid = shardID[0]\n\t} else {\n\t\tid = s.GetLatestShardID()\n\t}\n\tif id >= s.GetShardNum() || id < 0 {\n\t\treturn nil, errors.New(errors.ErrorTypeRuntimeException, \"second shard not found\")\n\t}\n\ts.lock.RLock()\n\tsecondShard := s.shards[id]\n\ts.lock.RUnlock()\n\n\tsecondShard.lock.RLock()\n\tw := secondShard.writer\n\tsecondShard.lock.RUnlock()\n\tif w != nil {\n\t\treturn w, nil\n\t}\n\n\t// open writer\n\tif err := s.openWriter(id); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// check WAL","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/zincsearch/zincsearch/blob/dd2f8afd6562d4d52c41b2c5d312280e684a25ba/pkg/core/index_shards.go#L143-L179","documentation":"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).","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nw, err := idx.GetWriter(7) // only 4 shards exist\n// after\nif shardID < 0 || shardID >= idx.GetShardNum() {\n    return fmt.Errorf(\"shard %d out of range (0..%d)\", shardID, idx.GetShardNum()-1)\n}\nw, err := idx.GetWriter(shardID)","handlingStrategy":"validation","validationCode":"func safeShardID(idx *core.Index, id uint64) bool {\n    return id < uint64(idx.GetShardNum())\n}\n// call only if safeShardID(idx, shardID) before GetWriter(shardID)","typeGuard":"func shardInRange(id int, shardNum int) bool { return id >= 0 && id < shardNum }","tryCatchPattern":"w, err := idx.GetWriter(shardID)\nif err != nil && strings.Contains(err.Error(), \"second shard not found\") {\n    // repair index state or fall back to a valid shard\n    w, err = idx.GetWriter(0)\n}","preventionTips":["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."],"tags":["sharding","index","out-of-range","runtime"],"backgroundTag":"shard-not-found","analyzedSha":"dd2f8afd6562d4d52c41b2c5d312280e684a25ba","analyzedAt":"2026-09-03T00:22:38.551Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T07:17:11.731Z"}