temporalio/temporal · warning
failed to get caller info for metric definition
Error message
failed to get caller info for metric definition
What it means
newMetricDefinition uses runtime.Caller(2) to record the source file and line where a metric was declared, for debugging/metric-attribution purposes. If runtime.Caller fails to walk the stack (extremely rare; can happen with inlined or manipulated stacks, e.g. runtime tricks, -gcflags=-l mismatches, or calling via reflect/assembly wrappers), the library panics. It is a programmer-error invariant, not a runtime condition.
Source
Thrown at common/metrics/defs_base.debug.go:26
// metricDefinition contains the definition for a metric
type metricDefinition struct {
name string
description string
unit MetricUnit
file string
line int
}
func newMetricDefinition(name string, opts ...Option) metricDefinition {
d := metricDefinition{
name: name,
description: "",
unit: "",
}
_, file, line, ok := runtime.Caller(2)
if !ok {
panic("failed to get caller info for metric definition")
}
d.file = file
d.line = line
for _, opt := range opts {
opt.apply(&d)
}
return d
}
func (md metricDefinition) Name() string {
return md.name
}
func (md metricDefinition) Unit() MetricUnit {
return md.unit
}
func (md metricDefinition) File() string {View on GitHub (pinned to bde624efd1)
Solutions
- Check that metric definitions are created directly through the provided constructor/vars helpers, not through extra intermediate wrappers that shift the stack depth
- If you added a wrapper layer, adjust the runtime.Caller depth in defs_base.debug.go accordingly
- Rebuild without nonstandard compiler flags that may suppress inlining assumptions
- Report upstream if it reproduces with stock metric definition calls
Example fix
// before
_, file, line, ok := runtime.Caller(2)
if !ok {
panic("failed to get caller info for metric definition")
}
// after
_, file, line, ok := runtime.Caller(1) // depth adjusted for new wrapper layer
if !ok {
file, line = "unknown", 0 // degrade gracefully instead of panicking
} Defensive patterns
Strategy: fallback
Prevention
- Create metric definitions only through the provided package helpers so the stack-depth assumption in runtime.Caller(2) holds
- Avoid adding intermediate wrapper functions around metric definition constructors
- Avoid nonstandard build flags that change inlining around metric definitions
When it happens
Trigger: Defining a metric via newMetricDefinition (any metric definition constructor) in a context where runtime.Caller(2) returns ok=false — practically only when the call stack is shorter than expected or the code path is invoked through non-standard stack manipulation.
Common situations: Refactoring metric definition helpers so the stack depth no longer matches the hardcoded Caller(2) offset; unusual build flags affecting inlining; exotic code generation wrappers.
Related errors
- not implemented
- 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/204a575fae182232.
Report an issue: GitHub.