{"record":{"id":"e32eaf186d7184b8","repo":"apache/seatunnel","slug":"get-job-state-error","errorCode":null,"errorMessage":"get job state error","messagePattern":"get job state error","errorType":"exception","errorClass":"SeaTunnelEngineException","httpStatus":null,"severity":"error","filePath":"seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/CoordinatorService.java","lineNumber":1556,"sourceCode":"                                    executorService));\n        }\n        return new PassiveCompletableFuture<>(voidCompletableFuture);\n    }\n\n    public PassiveCompletableFuture<JobResult> waitForJobComplete(long jobId) {\n        // must wait for all job restore complete\n        restoreAllJobFromMasterNodeSwitchFuture.join();\n        JobMaster runningJobMaster = getJobMaster(jobId);\n        if (runningJobMaster == null) {\n            // Because operations on Imap cannot be performed within Operation.\n            CompletableFuture<JobHistoryService.JobState> jobStateFuture =\n                    CompletableFuture.supplyAsync(\n                            () -> jobHistoryService.getJobDetailState(jobId), executorService);\n            JobHistoryService.JobState jobState = null;\n            try {\n                jobState = jobStateFuture.get();\n            } catch (Exception e) {\n                throw new SeaTunnelEngineException(\"get job state error\", e);\n            }\n\n            CompletableFuture<JobResult> future = new CompletableFuture<>();\n            if (jobState == null) {\n                future.complete(new JobResult(JobStatus.UNKNOWABLE, null));\n            } else {\n                future.complete(new JobResult(jobState.getJobStatus(), jobState.getErrorMessage()));\n            }\n            return new PassiveCompletableFuture<>(future);\n        } else {\n            return new PassiveCompletableFuture<>(runningJobMaster.getJobMasterCompleteFuture());\n        }\n    }\n\n    public PassiveCompletableFuture<Void> cancelJob(long jobId) {\n        JobMaster runningJobMaster = getJobMaster(jobId);\n        if (runningJobMaster == null) {\n            CompletableFuture<Void> future = new CompletableFuture<>();","sourceCodeStart":1538,"sourceCodeEnd":1574,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/CoordinatorService.java#L1538-L1574","documentation":"getJobDetailState is queried asynchronously through jobHistoryService; if the future throws (failure inside getJobDetailState or while reading the history IMap), it is rethrown as a SeaTunnelEngineException with this message. The caller cannot obtain the job's state, so the wait-for-job API errors instead of returning a JobResult.","triggerScenarios":"Calling waitForJobComplete / getJobResult APIs when jobHistoryService.getJobDetailState(jobId) throws — e.g. IMap access failure, concurrent cleanup of history records, or executor rejection.","commonSituations":"Querying job state during cluster shutdown or a network partition; history records concurrently removed while read; serialization issues in stored job state data.","solutions":["Read the caused-by exception to identify the underlying failure in getJobDetailState.","Retry the query with backoff; transient IMap/cluster issues usually clear once the cluster is stable.","Verify the jobId exists in job history (getJobMetrics) before waiting on its detailed state.","Check cluster health (member liveness, IMap connectivity); restore history data if corrupted."],"exampleFix":"// before\nJobResult result = coordinatorService.waitForJobComplete(jobId).get();\n// after: tolerate transient state query failure\ntry {\n    JobResult result = coordinatorService.waitForJobComplete(jobId).get();\n} catch (ExecutionException e) {\n    if (e.getCause() instanceof SeaTunnelEngineException\n            && e.getCause().getMessage().contains(\"get job state error\")) {\n        Thread.sleep(5000); // retry after cluster stabilizes\n    } else { throw e; }\n}","handlingStrategy":"try-catch","validationCode":"// confirm the job exists in history before waiting on its state\nJobMetrics m = jobClient.getJobMetrics(jobId);\nif (m == null || m.equals(JobMetrics.empty())) {\n    // job unknown; skip waiting on detailed state\n}","typeGuard":null,"tryCatchPattern":"try {\n    JobResult result = coordinatorService.waitForJobComplete(jobId).get();\n} catch (ExecutionException e) {\n    if (e.getCause() instanceof SeaTunnelEngineException\n            && e.getCause().getMessage().contains(\"get job state error\")) {\n        // retry with backoff, or fall back to getJobMetrics for status\n    } else { throw e; }\n}","preventionTips":["Avoid querying job state during cluster shutdown or membership changes.","Retry state queries with backoff on transient IMap errors.","Keep job history retention enabled until consumers finish reading state.","Monitor cluster health to detect partitions that break IMap access."],"tags":["zeta-engine","job-state","job-history"],"backgroundTag":"database-query-failed","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"}