{"record":{"id":"334038e13633ff91","repo":"temporalio/temporal","slug":"no-spans-to-export","errorCode":null,"errorMessage":"no spans to export","messagePattern":"no spans to export","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/testing/testtelemetry/exporter.go","lineNumber":89,"sourceCode":"}\n\nfunc (c *memExporterClient) UploadTraces(\n\tctx context.Context,\n\tprotoSpans []*tracepb.ResourceSpans,\n) error {\n\tc.spansLock.Lock()\n\tdefer c.spansLock.Unlock()\n\n\tc.spans = append(c.spans, protoSpans...)\n\treturn nil\n}\n\nfunc (c *memExporterClient) Write(filename string) (string, error) {\n\tc.spansLock.Lock()\n\tdefer c.spansLock.Unlock()\n\n\tif len(c.spans) == 0 {\n\t\treturn \"\", errors.New(\"no spans to export\")\n\t}\n\n\tif err := os.MkdirAll(c.outDir, 0o755); err != nil {\n\t\treturn \"\", err\n\t}\n\n\tfilePath := filepath.Join(c.outDir, filename)\n\tfile, err := os.Create(filePath)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tdefer file.Close()\n\n\tmarshaler := &ptrace.JSONMarshaler{}\n\tunmarshaler := &ptrace.ProtoUnmarshaler{}\n\n\t// Write each ResourceSpan as a separate line.\n\tfor _, resourceSpan := range c.spans {","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/common/testing/testtelemetry/exporter.go#L71-L107","documentation":"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.","triggerScenarios":"Calling Write on the in-memory telemetry exporter before any span was recorded (c.spans is empty).","commonSituations":"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.","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"],"exampleFix":"// before\n_, err := client.Write(filename) // may fail with no spans\n// after\nclient.spansLock.Lock()\nhasSpans := len(client.spans) > 0\nclient.spansLock.Unlock()\nif hasSpans {\n    _, err := client.Write(filename)\n    require.NoError(t, err)\n}","handlingStrategy":"validation","validationCode":"if len(client.spans) == 0 {\n    t.Skip(\"no spans recorded; skipping telemetry export assertion\")\n}","typeGuard":null,"tryCatchPattern":"path, err := client.Write(filename)\nif err != nil && strings.Contains(err.Error(), \"no spans to export\") {\n    // verify traced code ran; do not treat as fatal if zero spans is expected\n}","preventionTips":["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"],"tags":["testing","telemetry","otel","exporter"],"backgroundTag":"no-spans-to-export","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}