temporalio/temporal · error
internal error: call to RetryLockedSource.Seed
Error message
internal error: call to RetryLockedSource.Seed
What it means
RetryLockedSource in common/backoff/retrypolicy.go is a math/rand.Source wrapper that is deliberately seeded once at construction (from time.Now().UnixNano()). Calling Seed on it afterwards would break retry-backoff determinism guarantees, so the method unconditionally panics with "internal error: call to RetryLockedSource.Seed". It marks an unsupported operation as a programmer error.
Source
Thrown at common/backoff/retrypolicy.go:339
// See the following discussions for details
// https://github.com/golang/go/issues/24121 <- main
// https://github.com/stripe/veneur/pull/466 -< make rng source faster
// https://github.com/golang/go/issues/25057
// https://github.com/golang/go/issues/21393
type RetryLockedSource struct {
lk sync.Mutex
s rand.Source
}
func (r *RetryLockedSource) Int63() int64 {
r.lk.Lock()
defer r.lk.Unlock()
return r.s.Int63()
}
func (r *RetryLockedSource) Seed(seed int64) {
panic("internal error: call to RetryLockedSource.Seed")
}
func NewRetryLockedSource() *RetryLockedSource {
return &RetryLockedSource{
lk: sync.Mutex{},
s: rand.NewSource(time.Now().UnixNano()),
}
}
View on GitHub (pinned to bde624efd1)
Solutions
- Remove the Seed call — RetryLockedSource is seeded automatically at NewRetryLockedSource()
- If deterministic seeding is needed, construct your own rand.NewSource(seed) instead of RetryLockedSource
- Audit code that accepts rand.Source to ensure it does not call Seed on the provided source
Example fix
// before src := backoff.NewRetryLockedSource() rnd := rand.New(src) rnd.Seed(42) // panics // after src := rand.NewSource(42) // deterministic test source rnd := rand.New(src)
Defensive patterns
Strategy: validation
Validate before calling
// Ensure no code path calls Seed on a source you don't own:
if s, ok := src.(*backoff.RetryLockedSource); ok {
_ = s // do not Seed; already seeded at construction
} Prevention
- Never call Seed on sources created by backoff helpers
- Use your own rand.NewSource(seed) when reproducibility is required
- Review generic code accepting rand.Source for implicit Seed calls
When it happens
Trigger: Calling (r *RetryLockedSource).Seed(seed int64) directly, or passing a RetryLockedSource to code that calls Seed on any rand.Source (e.g. rand.New(source).Seed(...), some shuffling/seeding utilities).
Common situations: Reusing a backoff policy helper that reseeds its source for reproducibility in tests; generic code that takes a rand.Source interface and defensively seeds it; wiring RetryLockedSource into a rand.Rand and then calling Seed on the Rand.
Related errors
- chasm visibilityTaskHandler should not be called directly
- Cannot use Put API in Pin mode. Use Delete and PutIfNotExist
- registrable component validation error: CHASM search attribu
- registrable component validation error: CHASM search attribu
- registrable component validation error: search attribute ali
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/3800490bcac5bd08.
Report an issue: GitHub.