{"record":{"id":"9af4bc7e64072e3d","repo":"apache/seatunnel","slug":"mdccontext-is-already-activated","errorCode":null,"errorMessage":"MDCContext is already activated","messagePattern":"MDCContext is already activated","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"seatunnel-api/src/main/java/org/apache/seatunnel/api/tracing/MDCContext.java","lineNumber":76,"sourceCode":"\n    private final Long jobId;\n    private final Long pipelineId;\n    private final Long taskId;\n    private transient volatile MDCContext toRestore;\n\n    public MDCContext(Long jobId, Long pipelineId, Long taskId) {\n        this.jobId = jobId;\n        this.pipelineId = pipelineId;\n        this.taskId = taskId;\n    }\n\n    public synchronized MDCContext activate() {\n        if (this == EMPTY) {\n            return this;\n        }\n\n        if (this.toRestore != null) {\n            throw new IllegalStateException(\"MDCContext is already activated\");\n        }\n        this.toRestore = current();\n\n        try {\n            if (jobId != null) {\n                MDC.put(JOB_ID, String.valueOf(jobId));\n            }\n            if (pipelineId != null) {\n                MDC.put(PIPELINE_ID, String.valueOf(pipelineId));\n            }\n            if (taskId != null) {\n                MDC.put(TASK_ID, String.valueOf(taskId));\n            }\n        } catch (Throwable e) {\n            log.error(\"Failed to put MDC context\", e);\n            throw e;\n        }\n        return this;","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-api/src/main/java/org/apache/seatunnel/api/tracing/MDCContext.java#L58-L94","documentation":"MDCContext.activate() installs job-id context into the SLF4J MDC and stores the previous context in toRestore. Activating the same MDCContext instance twice without closing it would overwrite toRestore and leak MDC state, so a second activate() on an already-active context throws IllegalStateException. EMPTY contexts are idempotent and exempt.","triggerScenarios":"Calling activate() twice on the same non-EMPTY MDCContext instance without close()/restore in between, e.g. wrapping a scope twice or activating in nested try-with-resources blocks sharing one instance.","commonSituations":"Tracing/observability code that opens the same context scope in both an outer wrapper and inner interceptor; accidental double-activation in job submission paths; reusing a cached MDCContext across sequential code blocks without deactivating.","solutions":["Activate each MDCContext exactly once, in a try-with-resources block","Use separate MDCContext instances for nested scopes instead of reusing one","Check whether an outer layer already activates the context (interceptors/filters) and remove the duplicate call","If you need re-entrancy, track activation yourself or use the context factory to create a fresh instance per scope"],"exampleFix":"// before\nMDCContext ctx = new MDCContext(jobId);\ntry (MDCContext a = ctx.activate()) {\n    try (MDCContext b = ctx.activate()) { // throws: already activated\n// after\nMDCContext ctx = new MDCContext(jobId);\ntry (MDCContext a = ctx.activate()) {\n    runInner(); // inner code uses ambient MDC, no second activate()\n}","handlingStrategy":"try-catch","validationCode":"// detect double activation before it throws:\n// structure code so each MDCContext instance is activated once\ntry (MDCContext ctx = new MDCContext(jobId).activate()) {\n    // scope\n}","typeGuard":null,"tryCatchPattern":"try {\n    mdcContext.activate();\n} catch (IllegalStateException e) {\n    // context already active in this scope — proceed without re-activating\n}","preventionTips":["Always use try-with-resources so close() restores state before reuse","Create a new MDCContext per scope; never share instances across nested activations","Audit interceptors/wrappers so only one layer activates the context","Treat MDCContext as non-reentrant single-use scope handle"],"tags":["mdc","tracing","state"],"backgroundTag":"invalid-state-transition","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}