router-for-me/CLIProxyAPI · error

credential concurrency lifecycle timing safety invariant ove

Error message

credential concurrency lifecycle timing safety invariant overflows

What it means

ValidateCredentialConcurrencyLifecycle sums nodeHeartbeatTimeout+reclaim-grace and cpa-heartbeat-timeout+cpa-cancel-bound using a checked addition; if either sum would overflow int64 nanoseconds (max ~292 years), the check reports an overflow instead of silently wrapping. Only reachable with absurdly huge duration values in config.

Source

Thrown at internal/config/credential_concurrency.go:181

	}
	if cfg.MaxLimit < 1 || cfg.MaxLimit > maxCredentialConcurrencyLimit {
		return fmt.Errorf("credential concurrency max limit must be between 1 and %d", maxCredentialConcurrencyLimit)
	}
	return nil
}

// ValidateCredentialConcurrencyLifecycle verifies the Home lifecycle timing safety invariant.
func ValidateCredentialConcurrencyLifecycle(nodeHeartbeatTimeout time.Duration, cfg CredentialConcurrencyConfig) error {
	if nodeHeartbeatTimeout <= 0 {
		return fmt.Errorf("credential concurrency lifecycle durations must be positive")
	}
	if errValidate := ValidateCredentialConcurrency(cfg); errValidate != nil {
		return errValidate
	}
	left, leftOverflow := addCredentialConcurrencyDuration(nodeHeartbeatTimeout, cfg.ReclaimGrace)
	right, rightOverflow := addCredentialConcurrencyDuration(cfg.CPAHeartbeatTimeout, cfg.CPACancelBound)
	if leftOverflow || rightOverflow {
		return fmt.Errorf("credential concurrency lifecycle timing safety invariant overflows")
	}
	if left <= right {
		return fmt.Errorf("node heartbeat timeout plus reclaim grace must exceed CPA heartbeat timeout plus cancel bound")
	}
	return nil
}

func addCredentialConcurrencyDuration(left time.Duration, right time.Duration) (time.Duration, bool) {
	if right > 0 && left > time.Duration(1<<63-1)-right {
		return 0, true
	}
	return left + right, false
}

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Bring all credential-concurrency durations back to sane magnitudes (seconds to minutes).
  2. If generating configs programmatically, verify unit conversions (time.Duration is nanoseconds; use time.Second multipliers).
  3. Re-validate after scaling down.

Example fix

# before (config.yaml)
credential-concurrency:
  cpa-heartbeat-timeout: 2562047h
  cpa-cancel-bound: 2562047h

# after
credential-concurrency:
  cpa-heartbeat-timeout: 3s
  cpa-cancel-bound: 5s
Defensive patterns

Strategy: validation

Validate before calling

// Go: sanity-cap durations before validation.
func saneDuration(d time.Duration) bool { return d > 0 && d < 24*time.Hour }

Prevention

When it happens

Trigger: credential-concurrency durations near time.Duration max, e.g. 'cpa-heartbeat-timeout: 2562047h' combined with a large cpa-cancel-bound, or any pair whose nanosecond sum exceeds 1<<63-1.

Common situations: Config generation bugs emitting huge numbers (e.g. milliseconds passed where nanoseconds expected via integer cast); copy-paste of a duration with too many zeros; effectively never seen with human-written values.

Related errors


AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15). Data as JSON: /api/errors/8ad8b9b2d3156e8b. Report an issue: GitHub.