{"record":{"id":"92f425745695ad57","repo":"vitessio/vitess","slug":"basekeyspace-is-required-for-snapshot-keyspaces","errorCode":null,"errorMessage":"BaseKeyspace is required for SNAPSHOT keyspaces","messagePattern":"BaseKeyspace is required for SNAPSHOT keyspaces","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtctl/grpcvtctldserver/server.go","lineNumber":933,"sourceCode":"\n// CreateKeyspace is part of the vtctlservicepb.VtctldServer interface.\nfunc (s *VtctldServer) CreateKeyspace(ctx context.Context, req *vtctldatapb.CreateKeyspaceRequest) (resp *vtctldatapb.CreateKeyspaceResponse, err error) {\n\tspan, ctx := trace.NewSpan(ctx, \"VtctldServer.CreateKeyspace\")\n\tdefer span.Finish()\n\n\tdefer panicHandler(&err)\n\n\tspan.Annotate(\"keyspace\", req.Name)\n\tspan.Annotate(\"keyspace_type\", topoproto.KeyspaceTypeLString(req.Type))\n\tspan.Annotate(\"force\", req.Force)\n\tspan.Annotate(\"allow_empty_vschema\", req.AllowEmptyVSchema)\n\tspan.Annotate(\"durability_policy\", req.DurabilityPolicy)\n\n\tswitch req.Type {\n\tcase topodatapb.KeyspaceType_NORMAL:\n\tcase topodatapb.KeyspaceType_SNAPSHOT:\n\t\tif req.BaseKeyspace == \"\" {\n\t\t\terr = errors.New(\"BaseKeyspace is required for SNAPSHOT keyspaces\")\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif req.SnapshotTime == nil {\n\t\t\terr = errors.New(\"SnapshotTime is required for SNAPSHOT keyspaces\")\n\t\t\treturn nil, err\n\t\t}\n\n\t\tspan.Annotate(\"base_keyspace\", req.BaseKeyspace)\n\t\tspan.Annotate(\"snapshot_time\", protoutil.TimeFromProto(req.SnapshotTime).String())\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unknown keyspace type %v\", req.Type)\n\t}\n\n\tki := &topodatapb.Keyspace{\n\t\tKeyspaceType:     req.Type,\n\t\tBaseKeyspace:     req.BaseKeyspace,\n\t\tSnapshotTime:     req.SnapshotTime,","sourceCodeStart":915,"sourceCodeEnd":951,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtctl/grpcvtctldserver/server.go#L915-L951","documentation":"CreateKeyspace validates that SNAPSHOT-type keyspaces carry a BaseKeyspace identifying the keyspace they were snapshotted from. Since a SNAPSHOT keyspace is a point-in-time copy of another keyspace, omitting the source keyspace leaves the snapshot unanchored and unusable, so the request is rejected before any topology mutation occurs.","triggerScenarios":"Calling vtctldclient CreateKeyspace (or the grpcvtctldserver CreateKeyspace RPC) with req.Type set to topodatapb.KeyspaceType_SNAPSHOT while req.BaseKeyspace is an empty string.","commonSituations":"CLI invocations that set --type=SNAPSHOT but forget --base-keyspace; programmatic keyspace creation scripts copying templates from NORMAL keyspaces; vitess-operator or plan reconcilers emitting partial Keyspace protos.","solutions":["Pass --base-keyspace <source-keyspace> (or set req.BaseKeyspace) when creating a SNAPSHOT keyspace","If a full independent keyspace is intended, omit --type so the keyspace is created as NORMAL","Set req.SnapshotTime as well, since it is validated immediately after BaseKeyspace"],"exampleFix":"// before\nreq := &vtctldatapb.CreateKeyspaceRequest{Type: topodatapb.KeyspaceType_SNAPSHOT}\n// after\nreq := &vtctldatapb.CreateKeyspaceRequest{\n  Type: topodatapb.KeyspaceType_SNAPSHOT,\n  BaseKeyspace: \"commerce\",\n  SnapshotTime: timestamppb.New(snapshotTime),\n}","handlingStrategy":"validation","validationCode":"if req.GetType() == topodatapb.KeyspaceType_SNAPSHOT && req.GetBaseKeyspace() == \"\" {\n    return fmt.Errorf(\"BaseKeyspace must be set for SNAPSHOT keyspace %s\", req.Name)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set both BaseKeyspace and SnapshotTime together when Type is SNAPSHOT","Add a client-side request builder that requires these fields for SNAPSHOT type","Default to NORMAL keyspace unless a snapshot copy is explicitly intended"],"tags":["vtctld","keyspace","validation","input-validation"],"backgroundTag":"missing-required-argument","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}