apache/seatunnel · error · IllegalArgumentException
Already an MDCComparator
Error message
Already an MDCComparator
What it means
MDCTracer.tracing(context, Comparator) rejects a delegate already wrapped as MDCComparator with IllegalArgumentException. Double wrapping would snapshot/restore MDC state twice around a single comparison, corrupting restoration order.
Solutions
- Trace the Comparator once, at the point where it is created
- Pass through already-wrapped comparators: `if (c instanceof MDCComparator) return c;`
- Deduplicate tracing across the utility and call-site layers
Example fix
// before MDCComparator<T> c = MDCTracer.tracing(jobId, MDCTracer.tracing(jobId, cmp)); // after MDCComparator<T> c = MDCTracer.tracing(jobId, cmp);
Defensive patterns
Strategy: type-guard
Validate before calling
MDCComparator<T> safeWrap(Long jobId, Comparator<T> c) {
return c instanceof MDCComparator ? (MDCComparator<T>) c : MDCTracer.tracing(jobId, c);
} Type guard
boolean isWrapped(Comparator<?> c) {
return c instanceof MDCComparator;
} Try / catch
try {
return MDCTracer.tracing(jobId, comparator);
} catch (IllegalArgumentException e) {
return (MDCComparator<T>) comparator;
} Prevention
- Trace comparators once at creation
- Pass through already-wrapped comparators in sort/merge utilities
- Keep tracing responsibility in a single factory per comparator type
When it happens
Trigger: Calling tracing(jobId, comparator) or tracing(context, comparator) where comparator is already an MDCComparator from a previous tracing() call, e.g. sort comparators wrapped by both a sort utility and the caller.
Common situations: Sorting/merging code where a shared comparator factory already applies tracing and the call site wraps again.
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
- Already an MDCCallable
- Already an MDCConsumer
- Already an MDCExecutor
- Already an MDCFunction
- Already an MDCPredicate
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/147d0418ea478d8e.
Report an issue: GitHub.
Appendix: source
Thrown at seatunnel-api/src/main/java/org/apache/seatunnel/api/tracing/MDCTracer.java:188
public static <T> MDCPredicate<T> tracing(MDCContext context, Predicate<T> delegate) {
if (delegate instanceof MDCPredicate) {
throw new IllegalArgumentException("Already an MDCPredicate");
}
return new MDCPredicate<>(context, delegate);
}
public static <T> MDCComparator<T> tracing(Comparator<T> delegate) {
return tracing(MDCContext.current(), delegate);
}
public static <T> MDCComparator<T> tracing(Long jobId, Comparator<T> delegate) {
return tracing(MDCContext.of(jobId), delegate);
}
public static <T> MDCComparator<T> tracing(MDCContext context, Comparator<T> delegate) {
if (delegate instanceof MDCComparator) {
throw new IllegalArgumentException("Already an MDCComparator");
}
return new MDCComparator<>(context, delegate);
}
public static <T> MDCSupplier<T> tracing(Supplier<T> delegate) {
return tracing(MDCContext.current(), delegate);
}
public static <T> MDCSupplier<T> tracing(Long jobId, Supplier<T> delegate) {
return tracing(MDCContext.of(jobId), delegate);
}
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);
}View on GitHub (pinned to cf67b549a7)