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

  1. Inspect the 'caused by' for the exact placeholder parse failure position
  2. Fix the placeholder syntax in startJobRunRequestJson — every '${...}' must be closed and reference a defined parameter
  3. Verify local/global parameters the placeholders refer to are defined on the workflow/task
  4. 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

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


AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06). Data as JSON: /api/errors/e1caf8bc9f9f400f. Report an issue: GitHub.