{"record":{"id":"95d5e8b710ae3dea","repo":"temporalio/temporal","slug":"request-to-priority-priority-to-rate-limiter-doe","errorCode":null,"errorMessage":"Request to priority & priority to rate limiter does not match","messagePattern":"Request to priority & priority to rate limiter does not match","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/quotas/priority_rate_limiter_impl.go","lineNumber":160,"sourceCode":"\n\tt := time.NewTimer(delay)\n\tdefer t.Stop()\n\tselect {\n\tcase <-t.C:\n\t\treturn nil\n\n\tcase <-ctx.Done():\n\t\treservation.CancelAt(time.Now())\n\t\treturn ctx.Err()\n\t}\n}\n\nfunc (p *PriorityRateLimiterImpl) getRateLimiters(\n\trequest Request,\n) (RequestRateLimiter, []RequestRateLimiter) {\n\tpriority := p.requestPriorityFn(request)\n\tif _, ok := p.priorityToRateLimiters[priority]; !ok {\n\t\tpanic(\"Request to priority & priority to rate limiter does not match\")\n\t}\n\n\trateLimiterIndex := p.priorityToIndex[priority]\n\treturn p.rateLimiters[rateLimiterIndex], p.rateLimiters[rateLimiterIndex+1:]\n}\n","sourceCodeStart":142,"sourceCodeEnd":166,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/common/quotas/priority_rate_limiter_impl.go#L142-L166","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Ensure every priority returned by requestPriorityFn is included in the priorityToRateLimiters map passed to NewPriorityRateLimiter","Fix the request priority function so it only returns registered priorities","Rebuild the priority rate limiter when the set of valid priorities changes"],"exampleFix":"// before\nfn := func(r quotas.Request) int { return r.Priority } // may return unregistered priority\n// after\nfn := func(r quotas.Request) int {\n    if _, ok := registeredPriorities[r.Priority]; !ok {\n        return defaultPriority\n    }\n    return r.Priority\n}","handlingStrategy":"validation","validationCode":"priority := requestPriorityFn(request)\nif _, ok := priorityToRateLimiters[priority]; !ok {\n    return fmt.Errorf(\"unregistered priority %d\", priority)\n}\n// only then call Allow/Reserve","typeGuard":null,"tryCatchPattern":"func() (ok bool) {\n    defer func() {\n        if recover() != nil { ok = false }\n    }()\n    return limiter.Allow(request, n)\n}()","preventionTips":["Keep requestPriorityFn and the priorityToRateLimiters map in sync","Unit test Allow/Reserve across every priority the priority function can emit","Rebuild the limiter whenever the priority set changes"],"tags":["go","panic","rate-limiting","configuration-mismatch"],"backgroundTag":"priority-limiter-mismatch","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}