{"record":{"id":"1857a90aaaedeace","repo":"AlexxIT/go2rtc","slug":"s-can-t-send-command-d-1857a9","errorCode":null,"errorMessage":"%s: can't send command %d","messagePattern":"(.+?): can't send command (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/xiaomi/miss/cs2/conn.go","lineNumber":238,"sourceCode":"\ttimeout := time.NewTicker(time.Second)\n\tdefer timeout.Stop()\n\n\tc.cmdAck = func() {\n\t\trepeat.Store(0)\n\t\ttimeout.Reset(1)\n\t}\n\n\tfor {\n\t\tif _, err := c.Conn.Write(req); err != nil {\n\t\t\treturn err\n\t\t}\n\t\t<-timeout.C\n\t\tr := repeat.Add(-1)\n\t\tif r < 0 {\n\t\t\treturn nil\n\t\t}\n\t\tif r == 0 {\n\t\t\treturn fmt.Errorf(\"%s: can't send command %d\", \"cs2\", cmd)\n\t\t}\n\t}\n}\n\nconst hdrSize = 32\n\nfunc (c *Conn) ReadPacket() (hdr, payload []byte, err error) {\n\tdata, ok := c.channels[2].Pop()\n\tif !ok {\n\t\treturn nil, nil, c.Error()\n\t}\n\treturn data[:hdrSize], data[hdrSize:], nil\n}\n\nfunc (c *Conn) WritePacket(hdr, payload []byte) error {\n\tconst offset = 12\n\n\tn := hdrSize + uint32(len(payload))","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/xiaomi/miss/cs2/conn.go#L220-L256","documentation":"WriteCommand retries sending a command frame a bounded number of times; when all attempts are exhausted without success it returns \"cs2: can't send command %d\" identifying the command code. It means the command could not be delivered/acknowledged within the retry budget, usually because the connection is dead or the peer is unresponsive.","triggerScenarios":"Calling WriteCommand (public) while the worker has exited due to a read error (c.err set), or the peer never consumes/acks the command before the repeat counter and timeout expire.","commonSituations":"Calling WriteCommand after the connection dropped; peer device offline or hung; retry count configured too low for a slow or lossy link.","solutions":["Check the connection state (c.err) before calling WriteCommand; reconnect first if the worker has failed","Increase the retry count / retry timeout passed to WriteCommand for slow links","Verify the peer is online and responsive (ping via msgPing) before issuing the command","Implement command idempotency so a safe retry after reconnect does not double-execute the command"],"exampleFix":"// before\nif err := conn.WriteCommand(cmd, payload); err != nil {\n    return fmt.Errorf(\"send failed: %w\", err)\n}\n// after\nif conn.Err() != nil {\n    if err := conn.Reconnect(); err != nil {\n        return fmt.Errorf(\"reconnect failed: %w\", err)\n    }\n}\nif err := conn.WriteCommand(cmd, payload); err != nil {\n    return fmt.Errorf(\"send failed: %w\", err)\n}","handlingStrategy":"retry","validationCode":"// verify connectivity before sending a command\nfunc canSend(c *Conn) bool { return c != nil && c.Err() == nil }","typeGuard":"func sendable(c *Conn) bool { return c != nil && c.Err() == nil }","tryCatchPattern":"var err error\nfor i := 0; i < 3; i++ {\n    if canSend(conn) { break }\n    if err = conn.Reconnect(); err != nil { time.Sleep(backoff(i)); continue }\n}\nif err == nil { err = conn.WriteCommand(cmd, payload) }","preventionTips":["Check connection health before each command","Size retry count/timeout to the worst-case link latency","Ping the peer before critical commands","Make commands idempotent so retries are safe"],"tags":["timeout","retry","command","xiaomi-cs2"],"backgroundTag":"request-timeout","analyzedSha":"c245815e75e2a5fd60b4290f12bfc04e55a984d3","analyzedAt":"2026-09-07T11:47:02.965Z","contentChangedAt":"2026-09-07T11:47:02.965Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}