{"record":{"id":"72fb5645f3f52b91","repo":"vitessio/vitess","slug":"error-parsing-shard-name-v-v","errorCode":null,"errorMessage":"error parsing shard name %v: %v","messagePattern":"error parsing shard name (.+?): (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/discovery/topology_watcher.go","lineNumber":370,"sourceCode":"// TopologyWatcher. Each filter is a keyspace|shard entry, where shard\n// can either be a shard name, or a keyrange. All tablets that match\n// at least one keyspace|shard tuple will be forwarded by the\n// TopologyWatcher to its consumer.\nfunc NewFilterByShard(filters []string, opts ...Option) (*FilterByShard, error) {\n\tm := make(map[string][]*filterShard)\n\tfor _, filter := range filters {\n\t\tparts := strings.Split(filter, \"|\")\n\t\tif len(parts) != 2 {\n\t\t\treturn nil, fmt.Errorf(\"invalid FilterByShard parameter: %v\", filter)\n\t\t}\n\n\t\tkeyspace := parts[0]\n\t\tshard := parts[1]\n\n\t\t// extract keyrange if it's a range\n\t\tcanonical, kr, err := topo.ValidateShardName(shard)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error parsing shard name %v: %v\", shard, err)\n\t\t}\n\n\t\t// check for duplicates\n\t\tfor _, c := range m[keyspace] {\n\t\t\tif c.shard == canonical {\n\t\t\t\treturn nil, fmt.Errorf(\"duplicate %v/%v entry\", keyspace, shard)\n\t\t\t}\n\t\t}\n\n\t\tm[keyspace] = append(m[keyspace], &filterShard{\n\t\t\tkeyspace: keyspace,\n\t\t\tshard:    canonical,\n\t\t\tkeyRange: kr,\n\t\t})\n\t}\n\n\tfbs := &FilterByShard{\n\t\tfilters: m,","sourceCodeStart":352,"sourceCodeEnd":388,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/discovery/topology_watcher.go#L352-L388","documentation":"After splitting a filter into keyspace and shard, NewFilterByShard validates the shard portion with topo.ValidateShardName (which also extracts keyranges like '-80'). If the shard name is not syntactically valid, this error wraps the validation failure.","triggerScenarios":"Calling NewFilterByShard with a shard part that fails topo.ValidateShardName — e.g. mismatched keyrange boundaries ('80-40'), non-hex characters in a keyrange ('-gg'), or otherwise malformed range syntax.","commonSituations":"Hand-written shard ranges with reversed or non-hex boundaries; copy-paste of shard names with typos; confusion between numeric and keyrange-based shard naming in custom deployments.","solutions":["Read the wrapped %v error for the exact validation failure from topo.ValidateShardName.","Fix the keyrange syntax: boundaries must be 2-character hex strings in ascending order, e.g. '-80', '80-', '40-80'.","Use '-' (empty range = whole keyspace) if you meant to watch all shards.","Validate shard names with topo.ValidateShardName in a quick unit check before configuring."],"exampleFix":"// before\nNewFilterByShard([]string{\"commerce|80-40\"}) // reversed range\n// after\nNewFilterByShard([]string{\"commerce|40-80\"})","handlingStrategy":"validation","validationCode":"canonical, _, err := topo.ValidateShardName(shard)\nif err != nil {\n\treturn fmt.Errorf(\"shard %q invalid: %v\", shard, err)\n}\n_ = canonical","typeGuard":null,"tryCatchPattern":"fbs, err := discovery.NewFilterByShard(filters)\nif err != nil {\n\tlog.Exitf(\"bad shard name in tablet-filters: %v\", err)\n}","preventionTips":["Use 2-char hex boundaries in ascending order for keyranges ('40-80', not '80-40' or '-gg')","Run topo.ValidateShardName over shard names before writing configs","Copy shard names from the topology instead of typing them"],"tags":["configuration","sharding","parsing"],"backgroundTag":"invalid-shard-name","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}