{"record":{"id":"091fc9dff5da3481","repo":"larksuite/cli","slug":"bus-probe-encode-w","errorCode":null,"errorMessage":"bus probe: encode: %w","messagePattern":"bus probe: encode: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/event/consume/startup.go","lineNumber":107,"sourceCode":"\tlogPath := filepath.Join(core.GetConfigDir(), \"events\", event.SanitizeAppID(appID), \"bus.log\")\n\tfmt.Fprintln(errOut, \"[event] event bus exited unexpectedly.\")\n\tfmt.Fprintln(errOut, \"[event] please check app credentials (lark-cli config show) and retry.\")\n\tfmt.Fprintf(errOut, \"[event] logs: %s\\n\", logPath)\n\treturn nil, errs.NewInternalError(errs.SubtypeUnknown,\n\t\t\"failed to connect to event bus within %v (app=%s)\", dialTimeout, appID).\n\t\tWithHint(\"check app credentials (`lark-cli config show`) and retry; bus logs: %s\", logPath)\n}\n\n// probeAndDialBus distinguishes a healthy bus from a mid-shutdown listener via StatusQuery first.\nfunc probeAndDialBus(tr transport.IPC, addr string) (net.Conn, error) {\n\tprobe, err := tr.Dial(addr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tprobe.SetDeadline(time.Now().Add(2 * time.Second))\n\tif err := protocol.Encode(probe, protocol.NewStatusQuery()); err != nil {\n\t\tprobe.Close()\n\t\treturn nil, fmt.Errorf(\"bus probe: encode: %w\", err)\n\t}\n\tbr := bufio.NewReader(probe)\n\tline, err := protocol.ReadFrame(br)\n\tprobe.Close()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"bus probe: read status: %w\", err)\n\t}\n\tmsg, err := protocol.Decode(bytes.TrimRight(line, \"\\n\"))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"bus probe: decode status: %w\", err)\n\t}\n\tif _, ok := msg.(*protocol.StatusResponse); !ok {\n\t\treturn nil, fmt.Errorf(\"bus probe: expected StatusResponse, got %T\", msg)\n\t}\n\n\treturn tr.Dial(addr)\n}\n","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/event/consume/startup.go#L89-L125","documentation":"During startup, probeAndDialBus opens a probe connection to the local event bus, sets a 2s deadline, and writes a StatusQuery frame via protocol.Encode. If encoding/writing the status query fails, the probe is closed and the error is wrapped as 'bus probe: encode: %w', causing EnsureBus to fail startup rather than proceed against an unhealthy bus. This is a local IPC failure, not a remote API error.","triggerScenarios":"protocol.Encode(probe, protocol.NewStatusQuery()) returns an error during EnsureBus: broken pipe because the bus process died or closed the socket, connection reset, write deadline (2s) exceeded on a busy/unresponsive bus, or bus socket in a bad state.","commonSituations":"Stale bus socket left over from a previous crashed run, bus process killed between connect and probe write, resource exhaustion making the local bus unresponsive, concurrent startup races where multiple consumers probe at once.","solutions":["Remove the stale bus socket/lock file and restart the CLI so a fresh bus is spawned.","Check whether the bus process is running and inspect its logs for crashes at probe time.","Retry the command once — transient write-deadline misses self-heal when the bus recovers.","If it persists, investigate protocol.Encode and the bus's read loop for version mismatch between writer and bus frame formats."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Verify the bus socket is alive before starting the full consumer\nconn, err := net.DialTimeout(\"unix\", busSocketPath, 2*time.Second)\nif err != nil {\n\t// bus not listening: clean stale socket and let EnsureBus respawn it\n} else {\n\tconn.Close()\n}","typeGuard":null,"tryCatchPattern":"cli, err := consume.EnsureBus(ctx, cfg)\nif err != nil {\n\tif strings.Contains(err.Error(), \"bus probe: encode\") || strings.Contains(err.Error(), \"bus probe: read status\") {\n\t\t// transient/unhealthy bus: remove stale socket and retry once\n\t\tos.Remove(busSocketPath) //nolint: local CLI-owned state\n\t\tcli, err = consume.EnsureBus(ctx, cfg)\n\t}\n\tif err != nil { return fmt.Errorf(\"bus startup failed: %w\", err) }\n}","preventionTips":["Clean up stale bus sockets/lock files after abnormal termination (signal handlers).","Probe with a short deadline and bounded retries instead of failing startup on the first attempt.","Keep the protocol writer and bus binary version-aligned; mismatched frame formats break Encode/ReadFrame.","Monitor the bus process health (restarts, OOM) in long-running environments."],"tags":["ipc","bus","startup","timeout"],"backgroundTag":"bus-unresponsive","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}