sipeed/picoclaw · error
invalid integer value: %s
Error message
invalid integer value: %s
What it means
Produced by parseFlexibleInt (pkg/auth/oauth.go:339) while decoding the interval field of the device-code response. The code first tries json.Unmarshal into int, then into string (accepting numeric strings); if both fail it rejects the value with 'invalid integer value: %s'. This means the JSON value is neither an integer nor a string — it is a float (e.g. 5.5), boolean, object, or array.
Source
Thrown at pkg/auth/oauth.go:339
if len(raw) == 0 || string(raw) == "null" {
return 0, nil
}
var interval int
if err := json.Unmarshal(raw, &interval); err == nil {
return interval, nil
}
var intervalStr string
if err := json.Unmarshal(raw, &intervalStr); err == nil {
intervalStr = strings.TrimSpace(intervalStr)
if intervalStr == "" {
return 0, nil
}
return strconv.Atoi(intervalStr)
}
return 0, fmt.Errorf("invalid integer value: %s", string(raw))
}
func LoginDeviceCode(cfg OAuthProviderConfig) (*AuthCredential, error) {
reqBody, _ := json.Marshal(map[string]string{
"client_id": cfg.ClientID,
})
resp, err := http.Post(
cfg.Issuer+"/api/accounts/deviceauth/usercode",
"application/json",
strings.NewReader(string(reqBody)),
)
if err != nil {
return nil, fmt.Errorf("requesting device code: %w", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)View on GitHub (pinned to 49183d7e8d)
Solutions
- Inspect the live response and confirm the JSON type of interval
- Fix the server/test fixture to emit an integer ("interval": 5) or a numeric string ("interval": "5")
- If fractional intervals are legitimate, extend parseFlexibleInt to unmarshal into float64 and truncate/round to int seconds
Example fix
// before (in parseFlexibleInt)
return 0, fmt.Errorf("invalid integer value: %s", string(raw))
// after (accept fractional seconds)
var intervalFloat float64
if err := json.Unmarshal(raw, &intervalFloat); err == nil {
return int(intervalFloat), nil
}
return 0, fmt.Errorf("invalid integer value: %s", string(raw)) Defensive patterns
Strategy: validation
Validate before calling
// Pre-check the interval field's JSON type before relying on the parse
var probe struct {
Interval json.RawMessage `json:"interval"`
}
if err := json.Unmarshal(body, &probe); err == nil {
if len(probe.Interval) > 0 {
var f float64
var s string
if json.Unmarshal(probe.Interval, &f) == nil || json.Unmarshal(probe.Interval, &s) == nil {
// number or string: parseFlexibleInt will accept it
}
}
} Type guard
func isInvalidIntervalError(err error) bool {
return err != nil && strings.Contains(err.Error(), "invalid integer value")
} Try / catch
if _, err := auth.RequestDeviceCode(cfg); err != nil {
if isInvalidIntervalError(err) {
// server contract changed: interval is neither number nor string
return fmt.Errorf("provider interval field has unsupported type: %w", err)
}
return err
} Prevention
- Contract-test the provider's interval field type on every provider API version bump
- Keep mock servers byte-compatible with production responses
- Prefer integer intervals when you control the server
- Extend parseFlexibleInt for float intervals if the provider legitimately sends them
When it happens
Trigger: The deviceauth/usercode response contains "interval": 5.5, "interval": true, "interval": {}, or "interval": []. Note: a non-numeric string like "abc" instead surfaces a strconv.Atoi error, and null/missing/empty-string interval are accepted as 0.
Common situations: Provider starts returning a fractional polling interval or switches interval to an object like {"seconds":5}; an API gateway rewriting the payload; a mocked/stubbed test server emitting JSON typed differently from production.
Related errors
- parsing device code response: %w
- parsing token response: %w
- failed to unmarshal response: %w
- marshal result: %w
- marshal request: %w
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/d47275c2f3cd5a3c.
Report an issue: GitHub.