apache/dolphinscheduler · error · EmrServerlessTaskException
Failed to resolve parameter placeholders
Error message
Failed to resolve parameter placeholders
What it means
buildStartJobRunRequest resolves ${placeholders} in the user-supplied startJobRunRequestJson via ParameterUtils.convertParameterPlaceholders. Any exception during placeholder substitution is wrapped as EmrServerlessTaskException with this message, so the request JSON is never sent to AWS.
Source
Thrown at dolphinscheduler-task-plugin/dolphinscheduler-task-emr-serverless/src/main/java/org/apache/dolphinscheduler/plugin/task/emrserverless/EmrServerlessTask.java:219
return Collections.emptyList();
}
@Override
public AbstractParameters getParameters() {
return emrServerlessParameters;
}
/**
* Build StartJobRunRequest from parameters and user-provided JSON.
*/
private StartJobRunRequest buildStartJobRunRequest() {
String startJobRunRequestJson;
try {
startJobRunRequestJson = ParameterUtils.convertParameterPlaceholders(
emrServerlessParameters.getStartJobRunRequestJson(),
ParameterUtils.convert(taskExecutionContext.getPrepareParamsMap()));
} catch (Exception e) {
throw new EmrServerlessTaskException("Failed to resolve parameter placeholders", e);
}
StartJobRunRequest request;
try {
request = objectMapper.readValue(startJobRunRequestJson, StartJobRunRequest.class);
} catch (JsonProcessingException e) {
throw new EmrServerlessTaskException(
"Cannot parse StartJobRunRequest from JSON: " + startJobRunRequestJson, e);
}
// Override applicationId and executionRoleArn from top-level parameters
request.setApplicationId(emrServerlessParameters.getApplicationId());
request.setExecutionRoleArn(emrServerlessParameters.getExecutionRoleArn());
// Set job name if provided
if (StringUtils.isNotEmpty(emrServerlessParameters.getJobName())) {
request.setName(emrServerlessParameters.getJobName());
} else {View on GitHub (pinned to 02eac45a1b)
Solutions
- Inspect the 'caused by' for the exact placeholder parse failure position
- Fix the placeholder syntax in startJobRunRequestJson — every '${...}' must be closed and reference a defined parameter
- Verify local/global parameters the placeholders refer to are defined on the workflow/task
- Simplify: log or echo the rendered JSON in a shell task first to confirm substitution works
Example fix
// before
"entryPoint": "s3://bucket/${system.biz.date' // unterminated placeholder
// after
"entryPoint": "s3://bucket/${system.biz.date}/job.py" // closed, valid reference Defensive patterns
Strategy: validation
Validate before calling
// validate placeholders resolve before submitting
String json = emrServerlessParameters.getStartJobRunRequestJson();
if (json != null && (json.contains("${") && !json.matches("(?s).*\\$\\\\{[^}]*\\}.*"))) {
throw new IllegalArgumentException("Unbalanced placeholder in startJobRunRequestJson");
}
String resolved = ParameterUtils.convertParameterPlaceholders(json,
ParameterUtils.convert(taskExecutionContext.getPrepareParamsMap()));
if (resolved.contains("${")) log.warn("Unresolved placeholder remains in rendered JSON"); Try / catch
try {
buildStartJobRunRequest();
} catch (EmrServerlessTaskException e) {
if (e.getMessage().contains("Failed to resolve parameter placeholders")) {
log.error("Check '${...}' syntax and referenced parameter definitions", e);
}
throw e;
} Prevention
- Every '${...}' in startJobRunRequestJson must be closed and reference a defined local/global parameter
- Define expected parameters (e.g. system.biz.date) at workflow level before using them
- Preview rendered params in a test shell task before wiring into EMR Serverless JSON
- Avoid '${' characters that aren't placeholders (escape or restructure the JSON)
When it happens
Trigger: ParameterUtils.convertParameterPlaceholders throws on the startJobRunRequestJson or on converting prepareParamsMap — malformed placeholder syntax like an unterminated '${', a null startJobRunRequestJson, or unsupported escape sequences in the template.
Common situations: User wrote '${var' without closing brace in the task JSON; a business/launch date parameter name mismatched so substitution logic fails; taskParams JSON contains characters the parameter engine cannot process.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- EMR Serverless task params are not valid
- EMR Serverless task submit failed
- jobRunId is empty, cannot track application status
- EMR Serverless task tracking interrupted
- Failed to cancel EMR Serverless job run
AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06).
Data as JSON: /api/errors/e1caf8bc9f9f400f.
Report an issue: GitHub.