{"record":{"id":"570e8409eb969de2","repo":"benbjohnson/litestream","slug":"failed-to-marshal-request-w","errorCode":null,"errorMessage":"failed to marshal request: %w","messagePattern":"failed to marshal request: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/litestream/register.go","lineNumber":69,"sourceCode":"\n\t// Create HTTP client that connects via Unix socket with timeout.\n\tclientTimeout := time.Duration(*timeout) * time.Second\n\tclient := &http.Client{\n\t\tTimeout: clientTimeout,\n\t\tTransport: &http.Transport{\n\t\t\tDialContext: func(_ context.Context, _, _ string) (net.Conn, error) {\n\t\t\t\treturn net.DialTimeout(\"unix\", *socketPath, clientTimeout)\n\t\t\t},\n\t\t},\n\t}\n\n\treq := litestream.RegisterDatabaseRequest{\n\t\tPath:       dbPath,\n\t\tReplicaURL: replicaURL,\n\t}\n\treqBody, err := json.Marshal(req)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to marshal request: %w\", err)\n\t}\n\n\tresp, err := client.Post(\"http://localhost/register\", \"application/json\", bytes.NewReader(reqBody))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to connect to control socket: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tbody, err := io.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to read response: %w\", err)\n\t}\n\n\tif resp.StatusCode != http.StatusOK {\n\t\tvar errResp litestream.ErrorResponse\n\t\tif err := json.Unmarshal(body, &errResp); err == nil && errResp.Error != \"\" {\n\t\t\treturn fmt.Errorf(\"register failed: %s\", errResp.Error)\n\t\t}","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/cmd/litestream/register.go#L51-L87","documentation":"Before POSTing to the control socket, the register command serializes the RegisterDatabaseRequest (path + replica URL) with encoding/json. If json.Marshal fails, the request is wrapped as 'failed to marshal request'. In practice this is nearly impossible here because the payload contains only plain strings, so it signals a genuine internal invariant violation rather than user error.","triggerScenarios":"A json.Marshal failure on the RegisterDatabaseRequest struct — only reachable if the struct fields become unsupported types (e.g. channels/funcs/cycles) in a modified build; not reachable with string fields in the current code.","commonSituations":"Almost never hit by end users; may appear if a fork or patch adds a non-marshalable field to RegisterDatabaseRequest, or a custom json.Marshaler on it returns an error.","solutions":["Verify you are running an unmodified litestream build (rebuild from source)","Inspect the wrapped %w cause for the actual json.UnsupportedTypeError and check any custom MarshalJSON on RegisterDatabaseRequest","If reproducible in a fork, ensure added fields are JSON-encodable"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := registerCmd.Run(ctx, args); err != nil {\n    var e *fmt.wrapError\n    if errors.As(err, &e) && strings.Contains(err.Error(), \"failed to marshal request\") {\n        log.Fatalf(\"internal bug: non-marshalable request field: %v\", err)\n    }\n}","preventionTips":["Keep request structs limited to JSON-encodable types","Rebuild from upstream source if you see this error","Treat it as an internal-invariant bug and file an issue"],"tags":["json","serialization","cli"],"backgroundTag":"json-marshal-failed","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}