{"record":{"id":"ab13d92b6ee0da4c","repo":"vitessio/vitess","slug":"uncaught-panic-v-from-v","errorCode":null,"errorMessage":"uncaught panic: %v from: %v","messagePattern":"uncaught panic: (.+?) from: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtctl/grpcvtctldserver/server.go","lineNumber":127,"sourceCode":"\t\tts:  ts,\n\t\ttmc: tmc,\n\t\tws:  workflow.NewServer(env, ts, tmc),\n\t}\n}\n\n// NewTestVtctldServer returns a new VtctldServer for the given topo server\n// AND tmclient for use in tests. This should NOT be used in production.\nfunc NewTestVtctldServer(ts *topo.Server, tmc tmclient.TabletManagerClient) *VtctldServer {\n\treturn &VtctldServer{\n\t\tts:  ts,\n\t\ttmc: tmc,\n\t\tws:  workflow.NewServer(vtenv.NewTestEnv(), ts, tmc),\n\t}\n}\n\nfunc panicHandler(err *error) {\n\tif x := recover(); x != nil {\n\t\t*err = fmt.Errorf(\"uncaught panic: %v from: %v\", x, string(debug.Stack()))\n\t}\n}\n\n// AddCellInfo is part of the vtctlservicepb.VtctldServer interface.\nfunc (s *VtctldServer) AddCellInfo(ctx context.Context, req *vtctldatapb.AddCellInfoRequest) (resp *vtctldatapb.AddCellInfoResponse, err error) {\n\tspan, ctx := trace.NewSpan(ctx, \"VtctldServer.AddCellInfo\")\n\tdefer span.Finish()\n\n\tdefer panicHandler(&err)\n\n\tif req.CellInfo.Root == \"\" {\n\t\terr = vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, \"CellInfo.Root must be non-empty\")\n\t\treturn nil, err\n\t}\n\n\tspan.Annotate(\"cell\", req.Name)\n\tspan.Annotate(\"cell_root\", req.CellInfo.Root)\n\tspan.Annotate(\"cell_address\", req.CellInfo.ServerAddress)","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtctl/grpcvtctldserver/server.go#L109-L145","documentation":"VtctldServer wraps each RPC handler with panicHandler, converting any recovered panic into a structured error 'uncaught panic: %v from: %v' including the stack trace. It exists so a bug in a vtctld RPC implementation becomes an RPC error instead of crashing the whole vtctld process.","triggerScenarios":"Any vtctld RPC (AddCellInfo, AddCellsAlias, ApplyRoutingRules, ApplySchema, ApplyVSchema, Backup, etc.) whose implementation panics — nil pointer dereference on malformed requests, index out of range on empty topo results, assertion failures in called code.","commonSituations":"Sending requests with required fields unset (nil cell/topo options); topo corruption causing nil returns handled unsafely; bugs in a Vitess version triggered by unusual input — the panic message and stack point at the real cause.","solutions":["Read the embedded stack trace to find the panicking function and fix/upgrade the code.","Validate the request fields before calling (non-nil cell info, valid keyspace/table names).","Reproduce with a minimal request and file/check a Vitess bug if it's a library defect.","Retry after correcting input or topo state that triggered the nil dereference."],"exampleFix":"// before\nresp, err := client.AddCellInfo(ctx, &vtctldatapb.AddCellInfoRequest{}) // nil CellInfo panics server-side\n// after\nresp, err := client.AddCellInfo(ctx, &vtctldatapb.AddCellInfoRequest{\n    Name: \"zone1\",\n    CellInfo: &topodatapb.CellInfo{ServerAddress: \"etcd:2379\", Root: \"/vitess\"},\n})","handlingStrategy":"try-catch","validationCode":"// client-side: validate required request fields before sending\nif req.GetName() == \"\" || req.GetCellInfo() == nil {\n    return errors.New(\"AddCellInfo requires name and cellInfo\")\n}","typeGuard":"func isPanicError(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"uncaught panic:\")\n}","tryCatchPattern":"resp, err := client.AddCellInfo(ctx, req)\nif err != nil {\n    if isPanicError(err) {\n        // log full server stack from err and report/fix the request triggering it\n        log.Error(\"vtctld panicked\", slog.Any(\"error\", err))\n    }\n    return err\n}","preventionTips":["Populate all required proto fields before RPC calls","Read the stack trace embedded in the error to locate the panicking Vitess code","Test unusual inputs (empty keyspaces, missing cells) against vtcombo first","Upgrade/patch Vitess if the panic traces to a known bug"],"tags":["panic","vtctld","grpc"],"backgroundTag":"uncaught-panic-in-rpc","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}