apache/dolphinscheduler · error · EmrServerlessTaskException
jobRunId is empty, cannot track application status
Error message
jobRunId is empty, cannot track application status
What it means
trackApplicationStatus requires a jobRunId to poll GetJobRun. It first tries the in-memory field, then falls back to appIds persisted for failover recovery. If both are empty, it throws EmrServerlessTaskException with this message, because the plugin cannot identify which job run to monitor.
Source
Thrown at dolphinscheduler-task-plugin/dolphinscheduler-task-emr-serverless/src/main/java/org/apache/dolphinscheduler/plugin/task/emrserverless/EmrServerlessTask.java:157
log.info("Successfully submitted EMR Serverless job run, jobRunId: {}", jobRunId);
} catch (EmrServerlessTaskException | SdkBaseException e) {
log.error("EMR Serverless task submit failed", e);
throw new TaskException("EMR Serverless task submit failed", e);
}
}
@Override
public void trackApplicationStatus() throws TaskException {
try {
// Recover jobRunId from appIds if needed (failover case)
if (StringUtils.isEmpty(jobRunId) && StringUtils.isNotEmpty(getAppIds())) {
jobRunId = getAppIds();
log.info("Recovered EMR Serverless jobRunId from appIds: {}", jobRunId);
}
if (StringUtils.isEmpty(jobRunId)) {
throw new EmrServerlessTaskException("jobRunId is empty, cannot track application status");
}
String currentState = getJobRunState();
while (WAITING_STATES.contains(currentState)) {
TimeUnit.SECONDS.sleep(10);
currentState = getJobRunState();
}
final int exitCode = mapStateToExitCode(currentState);
setExitStatusCode(exitCode);
log.info("EMR Serverless job run [{}] finished with state: {}, exitCode: {}",
jobRunId, currentState, exitCode);
} catch (EmrServerlessTaskException | SdkBaseException e) {
log.error("EMR Serverless task tracking failed", e);
setExitStatusCode(TaskConstants.EXIT_CODE_FAILURE);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();View on GitHub (pinned to 02eac45a1b)
Solutions
- Ensure submitApplication completed and setAppIds(jobRunId) persisted appIds before tracking (check for earlier 'EMR Serverless task submit failed' errors)
- Re-run the task instance so a fresh jobRunId is submitted and stored
- If recovering manually, find the jobRunId in the AWS console/CloudTrail and set it as the task's appIds in the DB before retry
- Check the worker logs of the failed-over instance for the originally submitted jobRunId
Example fix
// before (worker died between submit and persist) jobRunId = result.getJobRunId(); // process killed here -> appIds lost // after jobRunId = result.getJobRunId(); setAppIds(jobRunId); // must run immediately after submit; add log/state persist so failover can recover
Defensive patterns
Strategy: validation
Validate before calling
// before relying on tracking/failover recovery
String jobRunId = getAppIds();
if (StringUtils.isBlank(jobRunId)) {
throw new IllegalStateException("appIds not persisted; cannot recover EMR Serverless jobRunId");
} Type guard
boolean hasTrackableJob(EmrServerlessTask t) {
return StringUtils.isNotEmpty(t.getAppIds());
} Try / catch
try {
task.trackApplicationStatus();
} catch (EmrServerlessTaskException e) {
if (e.getMessage().contains("jobRunId is empty")) {
log.error("No jobRunId persisted for failover; resubmit the task instance", e);
}
throw e;
} Prevention
- Always persist appIds immediately after StartJobRun (setAppIds is the failover source)
- Never skip submitApplication when tracking is expected in the same lifecycle
- Monitor for earlier submit failures before investigating tracking errors
- Test failover recovery by restarting a worker mid-run in staging
When it happens
Trigger: trackApplicationStatus is invoked without submitApplication having succeeded in this process and getAppIds() returns null/empty — typically after a worker failover where appIds was never persisted (submit crashed before setAppIds), or the task was defined so submitApplication is skipped.
Common situations: Worker crashed between StartJobRun success and setAppIds persistence; task instance retried on a different worker without stored appIds; DB row for appIds wiped or task configured to run track-only in custom code.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- EMR Serverless task params are not valid
- EMR Serverless task submit failed
- EMR Serverless task tracking interrupted
- Failed to cancel EMR Serverless job run
- Failed to resolve parameter placeholders
AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06).
Data as JSON: /api/errors/01c52cfe8923f9f7.
Report an issue: GitHub.