temporalio/temporal · error
not implemented
Error message
not implemented
What it means
priMetricHandler wraps the matching service's metrics handler to dual-record priority metrics. WithTags is intentionally unimplemented: the wrapper expects tags to be applied via the underlying handler methods (Counter/Histogram/Gauge return recorders that accept tags per call), so a WithTags call indicates a misuse of the handler API.
Source
Thrown at service/matching/pri_metrics_handler.go:67
}
func (p priMetricHandler) Stop(logger log.Logger) {
p.handler.Stop(logger)
}
func (p priMetricHandler) Counter(name string) metrics.CounterIface {
return priMetricsCounter{name: name, handler: p.handler}
}
func (p priMetricHandler) Timer(name string) metrics.TimerIface {
return priMetricsTimer{name: name, handler: p.handler}
}
func (p priMetricHandler) Gauge(name string) metrics.GaugeIface {
return priMetricsGauge{name: name, handler: p.handler}
}
func (p priMetricHandler) WithTags(...metrics.Tag) metrics.Handler {
panic("not implemented")
}
func (p priMetricHandler) Histogram(string, metrics.MetricUnit) metrics.HistogramIface {
panic("not implemented")
}
func (p priMetricHandler) StartBatch(string) metrics.BatchHandler {
panic("not implemented")
}
func (c priMetricsCounter) Record(i int64, tag ...metrics.Tag) {
c.handler.Counter(c.name).Record(i, tag...)
c.handler.Counter(withPriPrefix(c.name)).Record(i, tag...)
}
func (t priMetricsTimer) Record(duration time.Duration, tag ...metrics.Tag) {
t.handler.Timer(t.name).Record(duration, tag...)
t.handler.Timer(withPriPrefix(t.name)).Record(duration, tag...)View on GitHub (pinned to bde624efd1)
Solutions
- Do not call WithTags on priMetricHandler; pass tags per-record via the recorder methods (Counter(name).Record(v, tag...))
- If tags are required at handler level, implement WithTags to return a tag-applying wrapper over p.handler instead of panicking
- Use the embedded underlying handler (p.handler) when generic handler behavior is needed
Example fix
// before
h := p.priHandler // priMetricHandler
h.WithTags(metrics.StringTag("queue", qName)).Counter("foo").Record(1)
// after
h := p.handler // underlying metrics.Handler
h.WithTags(metrics.StringTag("queue", qName)).Counter("foo").Record(1) Defensive patterns
Strategy: validation
Validate before calling
// Never call WithTags on the pri wrapper; resolve the base handler first
if h, ok := handler.(metrics.Handler); ok && isPriMetricHandler(h) {
return fmt.Errorf("use underlying handler for WithTags")
} Try / catch
func safeWithTags(h metrics.Handler, tags ...metrics.Tag) (scoped metrics.Handler, err error) {
defer func() {
if rec := recover(); rec != nil {
err = fmt.Errorf("WithTags unsupported: %v", rec)
}
}()
return h.WithTags(tags...), nil
} Prevention
- Check the pri/fair handler contract before adding handler-level tagging in matching service code
- Apply tags per Record call instead of via WithTags when instrumenting priority metrics
- Keep a concrete list of which metrics.Handler methods the pri/fair wrappers support
When it happens
Trigger: Any code calling WithTags on a priMetricHandler — e.g. passing the wrapper where a generic metrics.Handler is expected and generic instrumentation code invokes WithTags to attach routing/scheduling tags.
Common situations: Refactors that thread a metrics.Handler through shared code without knowing the pri/fair wrappers only support the subset of the interface; new metric emissions added inside priority-task-queue code paths.
Related errors
- failed to get caller info for metric definition
- unable to create metrics handler: %w
- Current cluster name is empty
- Version increment <= 0 or > 2147483647
- <dynamic updateVersionToClusterName err>
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/a12cf53fa1d04c4b.
Report an issue: GitHub.