{"record":{"id":"2d28445290c72d23","repo":"nsqio/nsq","slug":"string-data","errorCode":null,"errorMessage":"string(data)","messagePattern":"string\\(data\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"bench/bench_reader/bench_reader.go","lineNumber":130,"sourceCode":"\tvar msgCount int64\n\tgo func() {\n\t\ttime.Sleep(td)\n\t\t_ = conn.Close()\n\t}()\n\tfor {\n\t\tresp, err := nsq.ReadResponse(rw)\n\t\tif err != nil {\n\t\t\tif errors.Is(err, net.ErrClosed) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tpanic(err.Error())\n\t\t}\n\t\tframeType, data, err := nsq.UnpackResponse(resp)\n\t\tif err != nil {\n\t\t\tpanic(err.Error())\n\t\t}\n\t\tif frameType == nsq.FrameTypeError {\n\t\t\tpanic(string(data))\n\t\t} else if frameType == nsq.FrameTypeResponse {\n\t\t\tcontinue\n\t\t}\n\t\tmsg, err := nsq.DecodeMessage(data)\n\t\tif err != nil {\n\t\t\tpanic(err.Error())\n\t\t}\n\t\t_, err = nsq.Finish(msg.ID).WriteTo(rw)\n\t\tif err != nil {\n\t\t\tpanic(err.Error())\n\t\t}\n\t\tmsgCount++\n\t\tif float64(msgCount%int64(*rdy)) > float64(*rdy)*0.75 {\n\t\t\terr = rw.Flush()\n\t\t\tif err != nil {\n\t\t\t\tpanic(err.Error())\n\t\t\t}\n\t\t}","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/nsqio/nsq/blob/85cf10c09c6c3c86160d6f0eb156f62d0efc1648/bench/bench_reader/bench_reader.go#L112-L148","documentation":"bench_reader panics with string(data) when the frame unpacked from a response has type FrameTypeError — nsqd sent an error frame mid-stream instead of a message. The panic message is the server's error text verbatim (e.g. 'E_INVALID', 'E_BAD_TOPIC', 'E_BAD_BODY', 'E_FAILED_ID'). At this point the subscription loop is running, so the error concerns the subscribed topic/channel or message processing state.","triggerScenarios":"Publishing to a topic that got deleted mid-benchmark (E_BAD_TOPIC / invalid topic); FIN sent for an ID already timed-out and requeued (E_FAILED_ID_NOT_WRITTEN); message body constraints violated by a concurrent producer (E_BAD_BODY, too large); channel deleted while bench_reader is attached.","commonSituations":"Running bench_writer and bench_reader against one topic while nsqdadmin deletes/recreates topics; message size exceeding --max-msg-size mid-run; long-running readers whose FINs race msg timeout (--msg-timeout) causing E_FAILED_ID; running other producers that violate topic-name rules (/topic is invalid).","solutions":["Match reader/writer topic names exactly and use valid topic strings (no slashes).","Raise --msg-timeout on nsqd or lower bench -rdy so messages are finished before timeout (avoids E_FAILED_ID_NOT_WRITTEN).","Ensure producers stay under --max-msg-size.","Do not delete/recreate the topic/channel while the benchmark loop is active."],"exampleFix":"# before\nnsqd --msg-timeout=100ms  # FINs race timeout -> E_FAILED_ID\nbench_reader -rdy=1000 ...\n\n# after\nnsqd --msg-timeout=60s\nbench_reader -rdy=200 ...","handlingStrategy":"try-catch","validationCode":"// preflight the exact topic/channel exist via HTTP\nresp, _ := http.Get(fmt.Sprintf(\"http://%s/topic/exists?topic=%s\", httpAddr, topic))\n// treat non-OK as fatal before connecting","typeGuard":null,"tryCatchPattern":"defer func() {\n    if r := recover(); r != nil {\n        log.Fatalf(\"nsqd error frame: %v\", r) // r is the server's error text\n    }\n}()","preventionTips":["Raise nsqd --msg-timeout above worst-case processing time to avoid E_FAILED_ID races.","Never delete the benchmark topic/channel mid-run via nsqadmin.","Keep producer message sizes under --max-msg-size."],"tags":["bench","nsq-client","panic","server-error-frame","protocol","go"],"backgroundTag":null,"analyzedSha":"85cf10c09c6c3c86160d6f0eb156f62d0efc1648","analyzedAt":"2026-08-16T00:53:05.009Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}