{"record":{"id":"e1caf8bc9f9f400f","repo":"apache/dolphinscheduler","slug":"failed-to-resolve-parameter-placeholders","errorCode":null,"errorMessage":"Failed to resolve parameter placeholders","messagePattern":"Failed to resolve parameter placeholders","errorType":"exception","errorClass":"EmrServerlessTaskException","httpStatus":null,"severity":"error","filePath":"dolphinscheduler-task-plugin/dolphinscheduler-task-emr-serverless/src/main/java/org/apache/dolphinscheduler/plugin/task/emrserverless/EmrServerlessTask.java","lineNumber":219,"sourceCode":"        return Collections.emptyList();\n    }\n\n    @Override\n    public AbstractParameters getParameters() {\n        return emrServerlessParameters;\n    }\n\n    /**\n     * Build StartJobRunRequest from parameters and user-provided JSON.\n     */\n    private StartJobRunRequest buildStartJobRunRequest() {\n        String startJobRunRequestJson;\n        try {\n            startJobRunRequestJson = ParameterUtils.convertParameterPlaceholders(\n                    emrServerlessParameters.getStartJobRunRequestJson(),\n                    ParameterUtils.convert(taskExecutionContext.getPrepareParamsMap()));\n        } catch (Exception e) {\n            throw new EmrServerlessTaskException(\"Failed to resolve parameter placeholders\", e);\n        }\n\n        StartJobRunRequest request;\n        try {\n            request = objectMapper.readValue(startJobRunRequestJson, StartJobRunRequest.class);\n        } catch (JsonProcessingException e) {\n            throw new EmrServerlessTaskException(\n                    \"Cannot parse StartJobRunRequest from JSON: \" + startJobRunRequestJson, e);\n        }\n\n        // Override applicationId and executionRoleArn from top-level parameters\n        request.setApplicationId(emrServerlessParameters.getApplicationId());\n        request.setExecutionRoleArn(emrServerlessParameters.getExecutionRoleArn());\n\n        // Set job name if provided\n        if (StringUtils.isNotEmpty(emrServerlessParameters.getJobName())) {\n            request.setName(emrServerlessParameters.getJobName());\n        } else {","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/apache/dolphinscheduler/blob/02eac45a1b6676e639fcbfb4be2243de5771b05d/dolphinscheduler-task-plugin/dolphinscheduler-task-emr-serverless/src/main/java/org/apache/dolphinscheduler/plugin/task/emrserverless/EmrServerlessTask.java#L201-L237","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\n\"entryPoint\": \"s3://bucket/${system.biz.date' // unterminated placeholder\n// after\n\"entryPoint\": \"s3://bucket/${system.biz.date}/job.py\" // closed, valid reference","handlingStrategy":"validation","validationCode":"// validate placeholders resolve before submitting\nString json = emrServerlessParameters.getStartJobRunRequestJson();\nif (json != null && (json.contains(\"${\") && !json.matches(\"(?s).*\\\\$\\\\\\\\{[^}]*\\\\}.*\"))) {\n    throw new IllegalArgumentException(\"Unbalanced placeholder in startJobRunRequestJson\");\n}\nString resolved = ParameterUtils.convertParameterPlaceholders(json,\n    ParameterUtils.convert(taskExecutionContext.getPrepareParamsMap()));\nif (resolved.contains(\"${\")) log.warn(\"Unresolved placeholder remains in rendered JSON\");","typeGuard":null,"tryCatchPattern":"try {\n    buildStartJobRunRequest();\n} catch (EmrServerlessTaskException e) {\n    if (e.getMessage().contains(\"Failed to resolve parameter placeholders\")) {\n        log.error(\"Check '${...}' syntax and referenced parameter definitions\", e);\n    }\n    throw e;\n}","preventionTips":["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)"],"tags":["aws","emr-serverless","parameters","template"],"backgroundTag":"invalid-argument-format","analyzedSha":"02eac45a1b6676e639fcbfb4be2243de5771b05d","analyzedAt":"2026-09-06T17:43:00.555Z","contentChangedAt":"2026-09-06T17:43:00.555Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}