temporalio/temporal · error
no spans to export
Error message
no spans to export
What it means
memExporterClient.Write dumps recorded OTel spans to a JSON file in the exporter's output directory. If no spans were collected, there is nothing to export, so it returns this error instead of writing an empty file. It is a guard against silently producing meaningless telemetry snapshots in tests.
Source
Thrown at common/testing/testtelemetry/exporter.go:89
}
func (c *memExporterClient) UploadTraces(
ctx context.Context,
protoSpans []*tracepb.ResourceSpans,
) error {
c.spansLock.Lock()
defer c.spansLock.Unlock()
c.spans = append(c.spans, protoSpans...)
return nil
}
func (c *memExporterClient) Write(filename string) (string, error) {
c.spansLock.Lock()
defer c.spansLock.Unlock()
if len(c.spans) == 0 {
return "", errors.New("no spans to export")
}
if err := os.MkdirAll(c.outDir, 0o755); err != nil {
return "", err
}
filePath := filepath.Join(c.outDir, filename)
file, err := os.Create(filePath)
if err != nil {
return "", err
}
defer file.Close()
marshaler := &ptrace.JSONMarshaler{}
unmarshaler := &ptrace.ProtoUnmarshaler{}
// Write each ResourceSpan as a separate line.
for _, resourceSpan := range c.spans {View on GitHub (pinned to bde624efd1)
Solutions
- Ensure the traced code path runs before calling Write (check the code under test actually emits spans)
- Confirm you are calling Write on the same memExporterClient that the tracer provider registered
- If exporting zero spans is legitimately expected, check len(c.spans) yourself before calling Write or treat the error as a no-op
Example fix
// before
_, err := client.Write(filename) // may fail with no spans
// after
client.spansLock.Lock()
hasSpans := len(client.spans) > 0
client.spansLock.Unlock()
if hasSpans {
_, err := client.Write(filename)
require.NoError(t, err)
} Defensive patterns
Strategy: validation
Validate before calling
if len(client.spans) == 0 {
t.Skip("no spans recorded; skipping telemetry export assertion")
} Try / catch
path, err := client.Write(filename)
if err != nil && strings.Contains(err.Error(), "no spans to export") {
// verify traced code ran; do not treat as fatal if zero spans is expected
} Prevention
- Run the instrumented code path before exporting
- Confirm the exporter under test is the one registered with the tracer provider
- Assert span count > 0 before Write
When it happens
Trigger: Calling Write on the in-memory telemetry exporter before any span was recorded (c.spans is empty).
Common situations: Test asserts telemetry before the instrumented code ran; wrong exporter instance consulted (spans recorded on a different client); the traced operation failed before emitting spans.
Related errors
- missing RespondWorkflowTaskCompletedRequest return
- history is nil
- history events are empty
- missing PollWorkflowTaskQueueResponse
- missing Legacy Query in PollWorkflowTaskQueueResponse
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/334038e13633ff91.
Report an issue: GitHub.