{"record":{"id":"6b85490167f66092","repo":"vitessio/vitess","slug":"w-shard-name-is-required","errorCode":null,"errorMessage":"%w: shard name is required","messagePattern":"%w: shard name is required","errorType":"validation","errorClass":"errors.ErrInvalidRequest","httpStatus":null,"severity":"error","filePath":"go/vt/vtadmin/cluster/cluster.go","lineNumber":477,"sourceCode":"\tdefer span.Finish()\n\n\tAnnotateSpan(c, span)\n\n\tif req == nil {\n\t\treturn nil, fmt.Errorf(\"%w: request cannot be nil\", errors.ErrInvalidRequest)\n\t}\n\n\tspan.Annotate(\"keyspace\", req.Keyspace)\n\tspan.Annotate(\"shard\", req.ShardName)\n\tspan.Annotate(\"force\", req.Force)\n\tspan.Annotate(\"include_parent\", req.IncludeParent)\n\n\tif req.Keyspace == \"\" {\n\t\treturn nil, fmt.Errorf(\"%w: keyspace name is required\", errors.ErrInvalidRequest)\n\t}\n\n\tif req.ShardName == \"\" {\n\t\treturn nil, fmt.Errorf(\"%w: shard name is required\", errors.ErrInvalidRequest)\n\t}\n\n\tif err := c.topoRWPool.Acquire(ctx); err != nil {\n\t\treturn nil, fmt.Errorf(\"CreateShard(%+v) failed to acquire topoRWPool: %w\", req, err)\n\t}\n\tdefer c.topoRWPool.Release()\n\n\treturn c.Vtctld.CreateShard(ctx, req)\n}\n\n// DeleteKeyspace deletes a keyspace in the given cluster, proxying a\n// DeleteKeyspaceRequest to a vtctld in that cluster.\nfunc (c *Cluster) DeleteKeyspace(ctx context.Context, req *vtctldatapb.DeleteKeyspaceRequest) (*vtctldatapb.DeleteKeyspaceResponse, error) {\n\tspan, ctx := trace.NewSpan(ctx, \"Cluster.DeleteKeyspace\")\n\tdefer span.Finish()\n\n\tAnnotateSpan(c, span)\n","sourceCodeStart":459,"sourceCodeEnd":495,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtadmin/cluster/cluster.go#L459-L495","documentation":"CreateShard requires req.ShardName to be non-empty; an empty shard name cannot identify a shard in the keyspace's shard ranges, so the function returns errors.ErrInvalidRequest wrapped with this message before acquiring the topo RW pool.","triggerScenarios":"Calling Cluster.CreateShard with a request that has ShardName unset/empty, e.g. &vtctldatapb.CreateShardRequest{Keyspace: \"commerce\"} with no shard name.","commonSituations":"API consumers omitting the shard name in the request body; tooling splitting \"keyspace/shard\" strings incorrectly so the shard part is empty; dash/UTF-8 shard range names mangled by URL encoding on the way in.","solutions":["Set req.ShardName to the desired shard name (e.g. \"0\", \"-80\", \"c0-\") before calling CreateShard.","Validate the shard name at your API boundary — non-empty and a valid keyrange/shard identifier.","If the shard name comes from a URL path, verify decoding preserved the full name (leading dashes especially)."],"exampleFix":"// before\nreq := &vtctldatapb.CreateShardRequest{Keyspace: \"commerce\"} // ShardName empty\n// after\nreq := &vtctldatapb.CreateShardRequest{Keyspace: \"commerce\", ShardName: \"-80\"}","handlingStrategy":"validation","validationCode":"if req.ShardName == \"\" {\n\treturn errors.New(\"shard name is required\")\n}\n// optional: verify it parses as a shard/keyrange identifier\nif _, err := key.ParseShardingSpec(req.ShardName); err != nil {\n\treturn fmt.Errorf(\"invalid shard name %q: %w\", req.ShardName, err)\n}","typeGuard":null,"tryCatchPattern":"resp, err := cluster.CreateShard(ctx, req)\nif err != nil {\n\tif errors.Is(err, vtadminerrors.ErrInvalidRequest) {\n\t\treturn status.Errorf(codes.InvalidArgument, \"invalid shard request: %v\", err)\n\t}\n\treturn err\n}","preventionTips":["Validate shard names (non-empty, valid keyrange format like \"-80\") before calling vtadmin.","Beware URL decoding dropping leading dashes from shard names in path parameters.","Use vtctldclient-style shard name validation in your own tooling."],"tags":["vtadmin","validation","invalid-request","shard"],"backgroundTag":"missing-required-argument","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}