benbjohnson/litestream · error
failed to parse response: %w
Error message
failed to parse response: %w
What it means
The daemon returned HTTP 200, but the response body could not be unmarshaled into litestream.StartResponse. The CLI wraps the json.Unmarshal error as 'failed to parse response'. This is a contract mismatch between daemon and CLI: truncated, non-JSON, or schema-drifted JSON.
Source
Thrown at cmd/litestream/start.go:84
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("failed to read response: %w", err)
}
if resp.StatusCode != http.StatusOK {
var errResp litestream.ErrorResponse
if err := json.Unmarshal(body, &errResp); err == nil && errResp.Error != "" {
return fmt.Errorf("start failed: %s", errResp.Error)
}
return fmt.Errorf("start failed: %s", string(body))
}
var result litestream.StartResponse
if err := json.Unmarshal(body, &result); err != nil {
return fmt.Errorf("failed to parse response: %w", err)
}
confirmation := StartStopResult{
Status: result.Status,
DBPath: result.Path,
State: "running",
TXID: result.TXID,
Socket: *socketPath,
}
if err := printStartStopResult(confirmation, *jsonOutput); err != nil {
return err
}
return nil
}
type StartStopResult struct {
Status string `json:"status"`View on GitHub (pinned to 4ed7a308f6)
Solutions
- Pin CLI and daemon to the same litestream version
- Fetch the raw body (curl --unix-socket /var/run/litestream.sock http://localhost/start) to inspect what the daemon actually returned
- Retry in case of a truncated response; check daemon logs for panics mid-write
- If persistent, file/inspect for a daemon bug writing malformed JSON on success
Defensive patterns
Strategy: type-guard
Validate before calling
// verify compatibility before parsing in wrappers: // compare `litestream version` output of daemon and CLI
Type guard
func validStartResponse(b []byte) bool {
var r litestream.StartResponse
return json.Unmarshal(b, &r) == nil && r.Status != ""
} Try / catch
var jsonErr *json.UnmarshalTypeError
if errors.As(err, &jsonErr) {
log.Printf("daemon/CLI schema mismatch at %s", jsonErr.Field)
} Prevention
- Upgrade daemon and CLI together
- Integration-test start -json output after version bumps
- Alert on any non-JSON bytes in IPC responses
When it happens
Trigger: Successful /start response whose body is truncated (connection cut after headers), is not JSON (proxy injected content), or whose fields don't match StartResponse because CLI and daemon versions differ.
Common situations: Upgrading the CLI but not the daemon (or vice versa) so response fields changed; a caching/proxy layer rewriting the body; daemon bug emitting partial JSON on success.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to parse response: %w
- failed to marshal request: %w
- failed to format response: %w
- failed to parse response: %w
- failed to format response: %w
AI-assisted analysis of benbjohnson/litestream@4ed7a308f6 (2026-09-06).
Data as JSON: /api/errors/5de9598792d415ca.
Report an issue: GitHub.