{"record":{"id":"138f7b79b162b95d","repo":"henrygd/beszel","slug":"failed-to-encode-request-w","errorCode":null,"errorMessage":"failed to encode request: %w","messagePattern":"failed to encode request: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/hub/transport/ssh.go","lineNumber":101,"sourceCode":"\t}\n\tdefer session.Close()\n\n\tstdout, err := session.StdoutPipe()\n\tif err != nil {\n\t\treturn err\n\t}\n\tstdin, err := session.StdinPipe()\n\tif err != nil {\n\t\treturn err\n\t}\n\tif err := session.Shell(); err != nil {\n\t\treturn err\n\t}\n\n\t// Send request\n\thubReq := common.HubRequest[any]{Action: action, Data: req}\n\tif err := cbor.NewEncoder(stdin).Encode(hubReq); err != nil {\n\t\treturn fmt.Errorf(\"failed to encode request: %w\", err)\n\t}\n\tstdin.Close()\n\n\t// Read response\n\tvar resp common.AgentResponse\n\tif err := cbor.NewDecoder(stdout).Decode(&resp); err != nil {\n\t\treturn fmt.Errorf(\"failed to decode response: %w\", err)\n\t}\n\n\tif resp.Error != \"\" {\n\t\treturn errors.New(resp.Error)\n\t}\n\n\tif err := session.Wait(); err != nil {\n\t\treturn err\n\t}\n\n\treturn UnmarshalResponse(resp, action, dest)","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/henrygd/beszel/blob/b38fb7dafa60812cc22e6a84ce313e94f1ce0a32/internal/hub/transport/ssh.go#L83-L119","documentation":"In transport.SSH Request (internal/hub/transport/ssh.go:101), the hub writes a HubRequest struct CBOR-encoded to the SSH session's stdin pipe; if cbor.NewEncoder(...).Encode fails it wraps the error as 'failed to encode request'. This indicates the write to the agent's stdin failed or the value is not CBOR-encodable.","triggerScenarios":"The SSH session/pipe broke while sending (agent process exited, session closed mid-write, broken pipe), or the request payload contains a type the fxamacker/cbor encoder cannot marshal (unsupported type like chan/func, invalid map key).","commonSituations":"Agent crashed or restarted while a request was in flight; session torn down by createSessionWithTimeout/timeout; unusual payload types passed as req for custom actions.","solutions":["Check the agent process is running on the remote host and the SSH session is healthy","Retry the request (RequestWithRetry already wraps this) after reconnecting the transport","Inspect the wrapped error: 'broken pipe'/'io: read/write on closed pipe' means reconnect; 'unsupported type' means fix the payload","Ensure req payloads use CBOR-serializable types (no funcs, channels, or unencodable maps)"],"exampleFix":"// before\nerr := transport.Request(ctx, action, reqWithChannel, &dest) // chan not CBOR-encodable\n// after\nerr := transport.Request(ctx, action, plainStructReq, &dest) // use encodable types","handlingStrategy":"retry","validationCode":"if !transport.IsConnected() {\n    return errors.New(\"transport disconnected; reconnect before requesting\")\n}","typeGuard":null,"tryCatchPattern":"err := t.Request(ctx, action, req, dest)\nif err != nil && strings.Contains(err.Error(), \"failed to encode request\") {\n    if strings.Contains(err.Error(), \"pipe\") {\n        return retryAfterReconnect(ctx, action, req, dest)\n    }\n    return err // payload type problem; do not blind-retry\n}","preventionTips":["Keep CBOR payloads to encodable types (no chan/func fields)","Use RequestWithRetry for transient pipe/session failures","Monitor agent liveness so broken sessions are detected early","Check wrapped error cause to distinguish reconnectable vs payload bugs"],"tags":["ssh","cbor","serialization"],"backgroundTag":"request-encode-failed","analyzedSha":"b38fb7dafa60812cc22e6a84ce313e94f1ce0a32","analyzedAt":"2026-08-31T15:10:10.149Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}