{"record":{"id":"574c77120c8054f7","repo":"vitessio/vitess","slug":"w-keyspace-name-is-required-574c77","errorCode":null,"errorMessage":"%w: keyspace name is required","messagePattern":"%w: keyspace name is required","errorType":"validation","errorClass":"errors.ErrInvalidRequest","httpStatus":null,"severity":"error","filePath":"go/vt/vtadmin/cluster/cluster.go","lineNumber":433,"sourceCode":"\tspan.Annotate(\"uuid\", req.Uuid)\n\n\treturn c.Vtctld.CompleteSchemaMigration(ctx, req)\n}\n\n// CreateKeyspace creates a keyspace in the given cluster, proxying a\n// CreateKeyspaceRequest to a vtctld in that cluster.\nfunc (c *Cluster) CreateKeyspace(ctx context.Context, req *vtctldatapb.CreateKeyspaceRequest) (*vtadminpb.Keyspace, error) {\n\tspan, ctx := trace.NewSpan(ctx, \"Cluster.CreateKeyspace\")\n\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\tif req.Name == \"\" {\n\t\treturn nil, fmt.Errorf(\"%w: keyspace name is required\", errors.ErrInvalidRequest)\n\t}\n\n\tspan.Annotate(\"keyspace\", req.Name)\n\n\tif err := c.topoRWPool.Acquire(ctx); err != nil {\n\t\treturn nil, fmt.Errorf(\"CreateKeyspace(%+v) failed to acquire topoRWPool: %w\", req, err)\n\t}\n\tdefer c.topoRWPool.Release()\n\n\tresp, err := c.Vtctld.CreateKeyspace(ctx, req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &vtadminpb.Keyspace{\n\t\tCluster:  c.ToProto(),\n\t\tKeyspace: resp.Keyspace,\n\t\tShards:   map[string]*vtctldatapb.Shard{},","sourceCodeStart":415,"sourceCodeEnd":451,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtadmin/cluster/cluster.go#L415-L451","documentation":"CreateKeyspace requires req.Name to be a non-empty keyspace name; when it is empty the function returns errors.ErrInvalidRequest wrapped with this message. A keyspace cannot be created in the topo server without a name, so the request is rejected before acquiring the topo RW pool or calling vtctld.","triggerScenarios":"Calling Cluster.CreateKeyspace with a request whose Name field is \"\" — e.g. &vtctldatapb.CreateKeyspaceRequest{} or a request built from an empty/unset user-supplied parameter.","commonSituations":"API consumers omitting the keyspace name in a POST body; CLI/tooling failing to populate the Name field; deserialization producing a zero-value request struct.","solutions":["Set req.Name to the desired keyspace name before calling CreateKeyspace.","Add caller-side validation of the keyspace name (non-empty, valid keyspace identifier) before issuing the call.","If the name comes from user input, reject empty values at your API boundary with a clear message."],"exampleFix":"// before\nreq := &vtctldatapb.CreateKeyspaceRequest{} // Name empty\n// after\nreq := &vtctldatapb.CreateKeyspaceRequest{Name: \"commerce\"}","handlingStrategy":"validation","validationCode":"if req.Name == \"\" {\n\treturn errors.New(\"keyspace name is required\")\n}","typeGuard":null,"tryCatchPattern":"resp, err := cluster.CreateKeyspace(ctx, req)\nvar inv *vtadminerrors.InvalidRequestError // via errors.Is\nif err != nil {\n\tif errors.Is(err, vtadminerrors.ErrInvalidRequest) {\n\t\treturn status.Errorf(codes.InvalidArgument, \"check keyspace name: %v\", err)\n\t}\n\treturn err\n}","preventionTips":["Validate user-supplied keyspace names (non-empty) at your HTTP/CLI boundary before calling vtadmin.","When parsing a \"keyspace/shard\" identifier, assert both parts are non-empty.","Add required-field checks to request-construction helpers."],"tags":["vtadmin","validation","invalid-request","keyspace"],"backgroundTag":"missing-required-argument","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}