AlexxIT/go2rtc · error
%d: %s
Error message
%d: %s
What it means
GetBaseURL calls the Roborock API and decodes a JSON envelope containing Code and Msg fields. When the server responds with a code other than 200, the function returns an error formatted as "<code>: <msg>". This is the library's way of surfacing Roborock API-level errors (auth failures, bad requests, rate limits) carried inside an otherwise successful HTTP response.
Solutions
- Read the numeric code and Msg in the error to identify the API failure (e.g. auth vs server error).
- Verify username/password or refresh the auth token, then retry.
- Use the correct regional base URL for your Roborock account (EU/US/CN etc.).
- Retry after a delay if the code indicates rate limiting or a transient server error.
Defensive patterns
Strategy: try-catch
Validate before calling
if baseURL == "" || username == "" || password == "" {
return errors.New("baseURL, username and password are required")
} Try / catch
url, err := roborock.GetBaseURL(client)
if err != nil {
var apiErr *roborock.APIError // or parse "<code>: <msg>"
// log code and message, decide whether to retry (5xx/throttle) or fail (auth)
return err
} Prevention
- Use the correct regional base URL for the account.
- Keep credentials/tokens fresh; re-login on auth-coded failures.
- Retry with backoff on transient server codes.
When it happens
Trigger: Calling GetBaseURL when the Roborock server rejects the request: invalid credentials, expired token, wrong endpoint region, or server-side error — any response whose JSON body has Code != 200.
Common situations: Wrong regional base URL for your account; expired login session; Roborock service outage or rate limiting; passing malformed credentials.
Related errors
- res.Status
- session request failed with status
- Code must be in the range [0, 125]
- err.Error()
- Method not allowed
AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07).
Data as JSON: /api/errors/8f06a9ca5ac6e7df.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/roborock/api.go:54
return "", err
}
client := http.Client{Timeout: time.Second * 5000}
res, err := client.Do(req)
var v struct {
Msg string `json:"msg"`
Code int `json:"code"`
Data struct {
URL string `json:"url"`
} `json:"data"`
}
if err = json.NewDecoder(res.Body).Decode(&v); err != nil {
return "", err
}
if v.Code != 200 {
return "", fmt.Errorf("%d: %s", v.Code, v.Msg)
}
return v.Data.URL, nil
}
func Login(baseURL, username, password string) (*UserInfo, error) {
u := baseURL + "/api/v1/login?username=" + url.QueryEscape(username) +
"&password=" + url.QueryEscape(password) + "&needtwostepauth=false"
req, err := http.NewRequest("POST", u, nil)
if err != nil {
return nil, err
}
clientID := core.RandString(16, 64)
clientID = base64.StdEncoding.EncodeToString([]byte(clientID))
req.Header.Set("header_clientid", clientID)
client := http.Client{Timeout: time.Second * 5000}View on GitHub (pinned to c245815e75)