{"record":{"id":"6e0eae4d9ef151e9","repo":"jaegertracing/jaeger","slug":"cannot-copy-stored-trace-w","errorCode":null,"errorMessage":"cannot copy stored trace: %w","messagePattern":"cannot copy stored trace: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/v2/memory/memory.go","lineNumber":189,"sourceCode":"// reader that modifies what it received would rewrite the stored trace for\n// every later reader. Query-time adjusters do exactly that — the adjuster\n// interface is documented as modifying a trace in place — as does any\n// query-interceptor extension that redacts attributes on the return path.\n//\n// This restores for the v2 store the guarantee #2720 added to the v1 store,\n// which was lost when the v1 implementation was deleted in #7711, and it uses\n// the same mechanism. A proto round-trip is the only copy that is deep for every\n// field: ptrace.Traces.CopyTo looks like the cheaper equivalent, but it assigns\n// bytes-valued attributes by slice (`ov.BytesValue = t.BytesValue` in pdata's\n// generated CopyAnyValue), leaving the clone sharing a backing array with the\n// store, which a reader can then rewrite through pcommon.ByteSlice.SetAt.\n// Nested array and kvlist values are copied properly, so bytes are the only\n// gap — but relying on that is how this class of bug survives, and the contract\n// this upholds promises callers a trace they may modify however they like.\nfunc cloneTrace(src ptrace.Traces) (ptrace.Traces, error) {\n\tbuf, err := marshalTraces(src)\n\tif err != nil {\n\t\treturn ptrace.Traces{}, fmt.Errorf(\"cannot copy stored trace: %w\", err)\n\t}\n\tdst, err := unmarshalTraces(buf)\n\tif err != nil {\n\t\treturn ptrace.Traces{}, fmt.Errorf(\"cannot copy stored trace: %w\", err)\n\t}\n\treturn dst, nil\n}\n\n// Indirected so that tests can exercise cloneTrace's error paths, which pdata\n// does not produce for a well-formed trace held by the store.\nvar (\n\tmarshalTraces   = new(ptrace.ProtoMarshaler).MarshalTraces\n\tunmarshalTraces = new(ptrace.ProtoUnmarshaler).UnmarshalTraces\n)\n\nfunc (st *Store) GetDependencies(ctx context.Context, query depstore.QueryParameters) ([]model.DependencyLink, error) {\n\tm := st.getTenant(tenancy.GetTenant(ctx))\n\treturn m.getDependencies(query)","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/jaegertracing/jaeger/blob/806f4447841ecdb60519f408b004a599d515f437/internal/storage/v2/memory/memory.go#L171-L207","documentation":"memory store's cloneTrace deep-copies a stored trace by marshal/unmarshal round-trip. If marshaling the source traces fails, it returns this error so callers never get a trace aliasing internal state — the memory store promises callers fully modifiable copies. pdata does not normally fail for well-formed traces, so this usually indicates corrupted internal state.","triggerScenarios":"Calling cloneTrace (via the memory store's read/copy paths) when marshalTraces(src) returns an error, e.g. corrupt pdata held in the store.","commonSituations":"Rare in practice; indicates a bug or corrupted in-memory trace data; surfaced in tests via the indirection hooks of marshalTraces/unmarshalTraces.","solutions":["Report/investigate the underlying marshal error — the stored trace is malformed","Re-ingest or evict the affected trace from the store","Check jaeger/pdata version compatibility if traces came from deserialization"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"clone, err := cloneTrace(src)\nif err != nil {\n    // stored trace is unusable: log wrapped cause, skip or evict trace\n    return fmt.Errorf(\"skipping corrupt trace: %w\", err)\n}","preventionTips":["Treat cloneTrace errors as store-corruption signals worth investigating","Keep pdata/jaeger versions consistent","Exercise the marshal/unmarshal indirection hooks in tests","Validate traces at ingestion boundaries"],"tags":["memory-store","deep-copy","serialization"],"backgroundTag":"trace-clone-failed","analyzedSha":"806f4447841ecdb60519f408b004a599d515f437","analyzedAt":"2026-09-01T02:39:22.140Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}