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   []string

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Remove quotes around the numeric value in config.toml (image_batch_window_ms = 500).
  2. Convert duration strings to plain integer milliseconds yourself ('500ms' → 500).
  3. 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

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


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/cde7422f561f95fb. Report an issue: GitHub.