{"record":{"id":"4fbe8adcbf3e779c","repo":"vitessio/vitess","slug":"uncaught-panic-v","errorCode":null,"errorMessage":"uncaught panic: %v","messagePattern":"uncaught panic: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"go/vt/binlog/updatestreamctl.go","lineNumber":293,"sourceCode":"\tf := tablesFilterFunc(tables, func(trans *binlogdatapb.BinlogTransaction) error {\n\t\ttablesStatements.Add(int64(len(trans.Statements)))\n\t\ttablesTransactions.Add(1)\n\t\treturn callback(trans)\n\t})\n\tbls := NewStreamer(updateStream.cp, updateStream.se, charset, pos, 0, f)\n\n\tstreamCtx, cancel := context.WithCancel(ctx)\n\ti := updateStream.streams.Add(cancel)\n\tdefer updateStream.streams.Delete(i)\n\n\treturn bls.Stream(streamCtx)\n}\n\n// HandlePanic is part of the UpdateStream interface\nfunc (updateStream *UpdateStreamImpl) HandlePanic(err *error) {\n\tif x := recover(); x != nil {\n\t\tlog.Error(fmt.Sprintf(\"Uncaught panic:\\n%v\\n%s\", x, tb.Stack(4)))\n\t\t*err = fmt.Errorf(\"uncaught panic: %v\", x)\n\t}\n}\n","sourceCodeStart":275,"sourceCodeEnd":296,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/binlog/updatestreamctl.go#L275-L296","documentation":"UpdateStreamImpl.HandlePanic is a deferred recover hook on UpdateStream RPCs. If a streaming handler panics, the panic is logged with a stack trace and converted into this returned error so callers get an RPC error instead of a crashed process.","triggerScenarios":"Any panic inside UpdateStream streaming methods (nil dereference, index out of range, vterrors of unexpected kind) recovered by HandlePanic via defer.","commonSituations":"Bugs in filter/streamer code triggered by unusual binlog events; concurrent shutdown racing a stream; malformed topo data causing nil maps.","solutions":["Check the preceding 'Uncaught panic:' log line for the panic value and stack trace.","Reproduce the panic with the specific binlog event/query shown and report/fix the underlying nil/edge-case bug.","Update Vitess — many streamer panics are fixed in later releases.","Retry the stream after the process recovers; the stream is terminated by the panic."],"exampleFix":"// before: panics on nil charset\nsvc.Register... stream(statement.Charset.String())\n// after: guard nil\nif statement.Charset != nil { ... }","handlingStrategy":"try-catch","validationCode":"// ensure stream inputs are non-nil before invoking UpdateStream RPCs\nif keyrange == nil || callback == nil {\n\treturn errors.New(\"keyrange and callback are required\")\n}","typeGuard":null,"tryCatchPattern":"defer func() {\n\tif r := recover(); r != nil {\n\t\tlog.Error(fmt.Sprintf(\"client-side stream panic: %v\\n%s\", r, debug.Stack()))\n\t\terr = fmt.Errorf(\"uncaught panic: %v\", r)\n\t}\n}()\nerr := updateStream.Stream(ctx, callback)","preventionTips":["Check the 'Uncaught panic:' log line with stack trace to find the root bug.","Keep Vitess updated; many streamer panics are fixed across releases.","Avoid racing stream shutdown (StreamStop vs active streams).","Fuzz-test filter rules with unusual binlog events before production."],"tags":["panic","streaming","recovery"],"backgroundTag":"uncaught-panic-recovered","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}