{"record":{"id":"252720f7cfb853c9","repo":"apache/seatunnel","slug":"already-an-mdcstream","errorCode":null,"errorMessage":"Already an MDCStream","messagePattern":"Already an MDCStream","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"seatunnel-api/src/main/java/org/apache/seatunnel/api/tracing/MDCTracer.java","lineNumber":218,"sourceCode":"\n    public static <T> MDCSupplier<T> tracing(MDCContext context, Supplier<T> delegate) {\n        if (delegate instanceof MDCSupplier) {\n            throw new IllegalArgumentException(\"Already an MDCSupplier\");\n        }\n        return new MDCSupplier<>(context, delegate);\n    }\n\n    public static <T> MDCStream<T> tracing(Stream<T> delegate) {\n        return tracing(MDCContext.current(), delegate);\n    }\n\n    public static <T> MDCStream<T> tracing(Long jobId, Stream<T> delegate) {\n        return tracing(MDCContext.of(jobId), delegate);\n    }\n\n    public static <T> MDCStream<T> tracing(MDCContext context, Stream<T> delegate) {\n        if (delegate instanceof MDCStream) {\n            throw new IllegalArgumentException(\"Already an MDCStream\");\n        }\n        return new MDCStream<>(context, delegate);\n    }\n}\n","sourceCodeStart":200,"sourceCodeEnd":223,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-api/src/main/java/org/apache/seatunnel/api/tracing/MDCTracer.java#L200-L223","documentation":"MDCTracer.tracing(MDCContext, Stream) wraps a Stream in an MDCStream so the MDC context is applied to stream operations. It rejects double-wrapping: if the delegate is already an MDCStream it throws IllegalArgumentException, preventing nested duplicated tracing wrappers.","triggerScenarios":"Calling MDCTracer.tracing(context, stream) where stream is already an MDCStream — e.g. tracing the same stream twice, or passing a stream produced by tracing(jobId, stream) back into tracing().","commonSituations":"Chaining stream factories that each apply tracing; re-tracing a stream after a map/peek step that returned the original wrapper; generic pipeline code that unconditionally calls tracing.","solutions":["Use the existing MDCStream directly; it is already a Stream","Remove the redundant tracing() call at one call site","Check with instanceof MDCStream before tracing and skip wrapping if already wrapped"],"exampleFix":"// before\nStream<T> traced = MDCTracer.tracing(jobId, stream);\nStream<T> again = MDCTracer.tracing(jobId, traced); // throws\n// after\nStream<T> traced = (stream instanceof MDCStream) ? stream : MDCTracer.tracing(jobId, stream);","handlingStrategy":"type-guard","validationCode":"if (!(stream instanceof MDCStream)) { stream = MDCTracer.tracing(jobId, stream); }","typeGuard":"static <T> Stream<T> ensureTraced(Stream<T> s, Long jobId) { return s instanceof MDCStream ? s : MDCTracer.tracing(jobId, s); }","tryCatchPattern":"try { return MDCTracer.tracing(jobId, stream); } catch (IllegalArgumentException e) { return stream; }","preventionTips":["Apply stream tracing only once, at stream creation","Use instanceof checks in generic pipeline code before wrapping","Keep tracing concerns in a single utility/factory layer"],"tags":["tracing","mdc","stream","argument-validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}