apache/seatunnel · error · IllegalArgumentException

Already an MDCStream

Error message

Already an MDCStream

What it means

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.

Source

Thrown at seatunnel-api/src/main/java/org/apache/seatunnel/api/tracing/MDCTracer.java:218

    public static <T> MDCSupplier<T> tracing(MDCContext context, Supplier<T> delegate) {
        if (delegate instanceof MDCSupplier) {
            throw new IllegalArgumentException("Already an MDCSupplier");
        }
        return new MDCSupplier<>(context, delegate);
    }

    public static <T> MDCStream<T> tracing(Stream<T> delegate) {
        return tracing(MDCContext.current(), delegate);
    }

    public static <T> MDCStream<T> tracing(Long jobId, Stream<T> delegate) {
        return tracing(MDCContext.of(jobId), delegate);
    }

    public static <T> MDCStream<T> tracing(MDCContext context, Stream<T> delegate) {
        if (delegate instanceof MDCStream) {
            throw new IllegalArgumentException("Already an MDCStream");
        }
        return new MDCStream<>(context, delegate);
    }
}

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Use the existing MDCStream directly; it is already a Stream
  2. Remove the redundant tracing() call at one call site
  3. Check with instanceof MDCStream before tracing and skip wrapping if already wrapped

Example fix

// before
Stream<T> traced = MDCTracer.tracing(jobId, stream);
Stream<T> again = MDCTracer.tracing(jobId, traced); // throws
// after
Stream<T> traced = (stream instanceof MDCStream) ? stream : MDCTracer.tracing(jobId, stream);
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(stream instanceof MDCStream)) { stream = MDCTracer.tracing(jobId, stream); }

Type guard

static <T> Stream<T> ensureTraced(Stream<T> s, Long jobId) { return s instanceof MDCStream ? s : MDCTracer.tracing(jobId, s); }

Try / catch

try { return MDCTracer.tracing(jobId, stream); } catch (IllegalArgumentException e) { return stream; }

Prevention

When it happens

Trigger: 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().

Common situations: 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.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/252720f7cfb853c9. Report an issue: GitHub.