chenhg5/cc-connect · error
expected number, got %T
Error message
expected number, got %T
What it means
Returned by coerceMilliseconds when a config value that must be numeric (e.g. image_batch_window_ms) is not an int/int64/float Go basic type. The %T verb reveals the actual Go type found, typically a string from TOML quoting or a nested map. newPlatform surfaces it wrapped by the invalid image_batch_window_ms/resource_chunk_size_bytes errors.
Source
Thrown at platform/feishu/feishu.go:286
switch x := v.(type) {
case int:
return int64(x), nil
case int32:
return int64(x), nil
case int64:
return x, nil
case uint:
return int64(x), nil
case uint32:
return int64(x), nil
case uint64:
return int64(x), nil
case float32:
return int64(x), nil
case float64:
return int64(x), nil
default:
return 0, fmt.Errorf("expected number, got %T", v)
}
}
// imageBatchEntry holds image data accumulated for one session while we wait
// to see if more images are coming. timer is stopped and replaced on every
// new image to coalesce the window; the pointer is captured by the timer
// callback so an in-flight (or stale) timer can detect that its entry has
// been superseded and exit without dispatching.
type imageBatchEntry struct {
sessionKey string
userID string
userName string
chatName string
rctx replyContext
quoted quotedMessage
onAccepted func()
images []core.ImageAttachment
messageIDs []stringView on GitHub (pinned to 4000b2338a)
Solutions
- Remove quotes around the numeric value in config.toml (image_batch_window_ms = 500).
- Convert duration strings to plain integer milliseconds yourself ('500ms' → 500).
- Check the %T in the message to see what type was parsed (e.g. string, bool, map).
Example fix
// before (config.toml) image_batch_window_ms = "500" // after image_batch_window_ms = 500
Defensive patterns
Strategy: validation
Validate before calling
v, ok := opts["image_batch_window_ms"]
switch v.(type) {
case int, int64, float32, float64:
// ok
default:
return fmt.Errorf("image_batch_window_ms must be a bare number, got %T", v)
} Type guard
func isNumber(v any) bool {
switch v.(type) {
case int, int64, float32, float64:
return true
}
return false
} Prevention
- Never quote numeric options in TOML.
- Validate config.toml at startup with a linter or cc-connect config check.
- Use plain integer milliseconds, not duration strings.
When it happens
Trigger: Setting image_batch_window_ms = "500" (string) or a table/bool in config.toml instead of a bare number, then starting the feishu platform.
Common situations: TOML quoting mistake: values copied from JSON configs keep quotes; users writing '500ms' as a duration string when only plain integers are accepted.
Related errors
- %s: invalid image_batch_window_ms %v: %w
- %s: invalid resource_chunk_size_bytes %v: %w
- %s: app_id and app_secret are required
- %s: invalid domain %q: %w
- %s: invalid progress_style %q (want legacy, compact, or card
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/cde7422f561f95fb.
Report an issue: GitHub.