AlexxIT/go2rtc · error

failed to marshal session request

Error message

failed to marshal session request: %w

What it means

Returned when json.Marshal fails on the session payload map built for the session creation request. The payload is a map[string]interface{} containing the hardware_id and device metadata, so marshal failures are rare but possible (e.g. values not JSON-serializable).

Solutions

  1. Inspect the wrapped error to identify which value failed to marshal
  2. Ensure hardwareID and all metadata values are JSON-serializable (strings, numbers, bools, maps, slices)
  3. Use standard library JSON-compatible types in the payload

Example fix

// before
payload["device"].(map[string]interface{})["metadata"]["fn"] = func(){} // unmarshalable
// after
payload["device"].(map[string]interface{})["metadata"]["version"] = "1.2.3"
Defensive patterns

Strategy: validation

Validate before calling

func isJSONSafe(v map[string]interface{}) bool {
    b, err := json.Marshal(v)
    return err == nil && b != nil
}
// call before constructing the client payload

Prevention

When it happens

Trigger: Calling the session-creation path where the sessionPayload map cannot be serialized by encoding/json (e.g. a non-marshalable value was placed in the metadata map).

Common situations: Custom code that modified the payload structure or hardware ID value types; unusual custom client configurations injecting unsupported types.

Understand the failure class

Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.

Related errors


AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07). Data as JSON: /api/errors/fb81f5f3e4f24469. Report an issue: GitHub.

Appendix: source

Thrown at pkg/ring/api.go:539

	// Make sure we have a valid auth token
	if err := c.ensureAuth(); err != nil {
		return fmt.Errorf("authentication failed while creating session: %w", err)
	}

	sessionPayload := map[string]interface{}{
		"device": map[string]interface{}{
			"hardware_id": c.hardwareID,
			"metadata": map[string]interface{}{
				"api_version":  apiVersion,
				"device_model": "ring-client-go",
			},
			"os": "android",
		},
	}

	body, err := json.Marshal(sessionPayload)
	if err != nil {
		return fmt.Errorf("failed to marshal session request: %w", err)
	}

	req, err := http.NewRequest("POST", ClientAPI("session"), bytes.NewReader(body))
	if err != nil {
		return err
	}

	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Accept", "application/json")
	req.Header.Set("Authorization", "Bearer "+c.authToken.AccessToken)
	req.Header.Set("hardware_id", c.hardwareID)
	req.Header.Set("User-Agent", "android:com.ringapp")

	resp, err := c.httpClient.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

View on GitHub (pinned to c245815e75)