{"record":{"id":"724c0bd79586b378","repo":"vitessio/vitess","slug":"the-shard-count-must-be-0-v","errorCode":null,"errorMessage":"the shard count must be > 0: %v","messagePattern":"the shard count must be > 0: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/key/key.go","lineNumber":342,"sourceCode":"\n// EvenShardsKeyRange returns a key range definition for a shard at index \"i\",\n// assuming range based sharding with \"n\" equal-width shards in total.\n// i starts at 0.\n//\n// Example: (1, 2) returns the second out of two shards in total i.e. \"80-\".\n//\n// This function must not be used in the Vitess code base because Vitess also\n// supports shards with different widths. In that case, the output of this\n// function would be wrong.\n//\n// Note: start and end values have trailing zero bytes omitted.\n// For example, \"80-\" has only the first byte (0x80) set.\n// We do this to produce the same KeyRange objects as ParseKeyRangeParts() does.\n// Because it's using the Go hex methods, it's omitting trailing zero bytes as\n// well.\nfunc EvenShardsKeyRange(i, n int) (*topodatapb.KeyRange, error) {\n\tif n <= 0 {\n\t\treturn nil, fmt.Errorf(\"the shard count must be > 0: %v\", n)\n\t}\n\tif i >= n {\n\t\treturn nil, fmt.Errorf(\"the index of the shard must be less than the total number of shards: %v < %v\", i, n)\n\t}\n\tif n&(n-1) != 0 {\n\t\treturn nil, fmt.Errorf(\"the shard count must be a power of two: %v\", n)\n\t}\n\n\t// Determine the number of bytes which are required to represent any\n\t// KeyRange start or end for the given n.\n\t// This is required to trim the returned values to the same length e.g.\n\t// (256, 512) should return 8000-8080 as shard key range.\n\tminBytes := 0\n\tfor nn := Uint64Key(n - 1); nn > 0; nn >>= 8 {\n\t\tminBytes++\n\t}\n\n\twidth := Uint64Key(math.MaxUint64)/Uint64Key(n) + 1","sourceCodeStart":324,"sourceCodeEnd":360,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/key/key.go#L324-L360","documentation":"EvenShardsKeyRange(i, n) computes the i-th keyrange when a keyspace is evenly split into n power-of-two shards. It throws this when n <= 0, because a non-positive shard count is meaningless and would cause division/modulo errors downstream.","triggerScenarios":"Calling EvenShardsKeyRange with n == 0 or n < 0, e.g. EvenShardsKeyRange(0, 0) or EvenShardsKeyRange(2, -4), typically from misparsed user input or a config that supplied an empty/invalid shard count.","commonSituations":"CLI/script passing an unset or zero shard count, config placeholder (e.g. '--shards=0') never filled in, integer parsing failures silently yielding 0.","solutions":["Pass a positive shard count (e.g. EvenShardsKeyRange(0, 256)).","Validate that the shard count is parsed correctly from flags/config before calling.","Guard the call: skip computing ranges until a valid n is available."],"exampleFix":"// before\ncount := cfg.Shards // 0 when unset\nkr, err := key.EvenShardsKeyRange(i, count)\n// after\nif cfg.Shards <= 0 {\n    return fmt.Errorf(\"--shards must be > 0\")\n}\nkr, err := key.EvenShardsKeyRange(i, cfg.Shards)","handlingStrategy":"validation","validationCode":"if shards <= 0 {\n\treturn fmt.Errorf(\"shard count must be > 0, got %d\", shards)\n}","typeGuard":null,"tryCatchPattern":"kr, err := key.EvenShardsKeyRange(i, n)\nif err != nil {\n\treturn nil, fmt.Errorf(\"even shards: %w\", err)\n}","preventionTips":["Validate flag/config shard counts are positive before computing ranges","Don't let failed parsing default silently to 0"],"tags":["go","sharding","input-validation"],"backgroundTag":"invalid-shard-count","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}