temporalio/temporal · error

Request to priority & priority to rate limiter does not matc

Error message

Request to priority & priority to rate limiter does not match

What it means

PriorityRateLimiterImpl.getRateLimiters maps a request's priority to its configured rate limiters via priorityToRateLimiters / priorityToIndex. It panics when the request resolves to a priority that was never registered, indicating the request-to-priority function and the priority-to-limiter map are out of sync.

Source

Thrown at common/quotas/priority_rate_limiter_impl.go:160

	t := time.NewTimer(delay)
	defer t.Stop()
	select {
	case <-t.C:
		return nil

	case <-ctx.Done():
		reservation.CancelAt(time.Now())
		return ctx.Err()
	}
}

func (p *PriorityRateLimiterImpl) getRateLimiters(
	request Request,
) (RequestRateLimiter, []RequestRateLimiter) {
	priority := p.requestPriorityFn(request)
	if _, ok := p.priorityToRateLimiters[priority]; !ok {
		panic("Request to priority & priority to rate limiter does not match")
	}

	rateLimiterIndex := p.priorityToIndex[priority]
	return p.rateLimiters[rateLimiterIndex], p.rateLimiters[rateLimiterIndex+1:]
}

View on GitHub (pinned to bde624efd1)

Solutions

  1. Ensure every priority returned by requestPriorityFn is included in the priorityToRateLimiters map passed to NewPriorityRateLimiter
  2. Fix the request priority function so it only returns registered priorities
  3. Rebuild the priority rate limiter when the set of valid priorities changes

Example fix

// before
fn := func(r quotas.Request) int { return r.Priority } // may return unregistered priority
// after
fn := func(r quotas.Request) int {
    if _, ok := registeredPriorities[r.Priority]; !ok {
        return defaultPriority
    }
    return r.Priority
}
Defensive patterns

Strategy: validation

Validate before calling

priority := requestPriorityFn(request)
if _, ok := priorityToRateLimiters[priority]; !ok {
    return fmt.Errorf("unregistered priority %d", priority)
}
// only then call Allow/Reserve

Try / catch

func() (ok bool) {
    defer func() {
        if recover() != nil { ok = false }
    }()
    return limiter.Allow(request, n)
}()

Prevention

When it happens

Trigger: Allow(request) or Reserve(request, n) where p.requestPriorityFn(request) returns a priority key absent from the map built at construction (e.g. priority values not present in priorityToRateLimiters).

Common situations: Changing the requestPriorityFn without rebuilding the limiter; passing a Request type/shape the priority function maps to an unexpected value; dynamic config adds priorities not present at limiter construction time.

Related errors


AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01). Data as JSON: /api/errors/95d5e8b710ae3dea. Report an issue: GitHub.