{"record":{"id":"49869c1c8d461781","repo":"apache/dolphinscheduler","slug":"datax-job-definition-is-missing-provide-inline-js","errorCode":null,"errorMessage":"DataX job definition is missing, provide inline json or attach exactly one .json resource file","messagePattern":"DataX job definition is missing, provide inline json or attach exactly one \\.json resource file","errorType":"exception","errorClass":"TaskException","httpStatus":null,"severity":"error","filePath":"dolphinscheduler-task-plugin/dolphinscheduler-task-datax/src/main/java/org/apache/dolphinscheduler/plugin/task/datax/DataxTask.java","lineNumber":211,"sourceCode":"        String fileName = String.format(\"%s/%s_job.json\", taskRequest.getExecutePath(), taskRequest.getTaskAppId());\n        String json;\n\n        Path path = new File(fileName).toPath();\n        if (Files.exists(path)) {\n            return fileName;\n        }\n\n        if (dataXParameters.getCustomConfig() == Flag.YES.ordinal()) {\n            // An attached resource file is a valid way to supply the job definition. Without\n            // this branch the worker downloads the resource but the plugin runs with the empty\n            // inline json and the job fails (issue #18389). Existing tasks created through the\n            // UI carry an empty object placeholder, treat it the same as no inline json.\n            if (dataXParameters.isInlineJsonAbsent()) {\n                // the job definition is the single attached .json resource, never the first\n                // entry in resourceList, which may be an auxiliary keytab or xml (issue #18389)\n                ResourceInfo jobResource = dataXParameters.getJobDefinitionResource();\n                if (jobResource == null) {\n                    throw new TaskException(\n                            \"DataX job definition is missing, provide inline json or attach exactly one .json resource file\");\n                }\n                json = readJsonFromResourceFile(jobResource);\n            } else {\n                json = dataXParameters.getJson();\n            }\n            json = json.replaceAll(\"\\\\r\\\\n\", System.lineSeparator());\n        } else {\n            ObjectNode job = JSONUtils.createObjectNode();\n            job.putArray(\"content\").addAll(buildDataxJobContentJson());\n            job.set(\"setting\", buildDataxJobSettingJson());\n\n            ObjectNode root = JSONUtils.createObjectNode();\n            root.set(\"job\", job);\n            root.set(\"core\", buildDataxCoreJson());\n            json = root.toString();\n        }\n","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/apache/dolphinscheduler/blob/02eac45a1b6676e639fcbfb4be2243de5771b05d/dolphinscheduler-task-plugin/dolphinscheduler-task-datax/src/main/java/org/apache/dolphinscheduler/plugin/task/datax/DataxTask.java#L193-L229","documentation":"buildDataxJsonFile() requires a DataX job definition from one of two sources: inline json in task params, or exactly one attached .json resource file. When isInlineJsonAbsent() is true (no inline json, or UI empty-object placeholder) and no dedicated .json job resource exists (getJobDefinitionResource() returns null), the task cannot build its json file and throws. Per issue #18389, auxiliary resources like keytab/xml files do not count as the job definition.","triggerScenarios":"Creating a DataX task with neither custom template json filled in nor a .json resource attached; attaching only non-.json resources (keytab, xml); UI leaving the inline json as an empty {} placeholder.","commonSituations":"Configuring a DataX task that relies on a Kerberos keytab resource but forgetting the actual .json job template; clearing the inline json in the UI; renaming/losing the .json resource so it no longer matches.","solutions":["Paste a complete DataX job json into the task's custom template (inline json) field, or","Attach exactly one .json resource file containing the DataX job definition.","If auxiliary files (keytab/xml) are needed, attach the .json job file in addition — it must be the sole .json resource.","Validate the task params in the UI before saving so the empty-object placeholder is not submitted."],"exampleFix":"// before: params with only an auxiliary resource\n{\"localParams\":[],\"resourceList\":[{\"resourceName\":\"hdfs.keytab\"}],\"json\":\"\"}\n// after: inline json provided\n{\"localParams\":[],\"resourceList\":[{\"resourceName\":\"hdfs.keytab\"}],\"json\":\"{\\\"job\\\":{\\\"content\\\":[...],\\\"setting\\\":{...}}}\"}","handlingStrategy":"validation","validationCode":"boolean ok = params.isInlineJsonPresent()\n    || (params.getResourceList() != null\n        && params.getResourceList().stream().filter(r -> r.getResourceName().endsWith(\".json\")).count() == 1);","typeGuard":null,"tryCatchPattern":"try {\n    dataxTaskHandle();\n} catch (TaskException e) {\n    if (e.getMessage().contains(\"job definition is missing\")) {\n        alert(\"Attach a .json DataX job resource or provide inline json\");\n    }\n}","preventionTips":["Always attach exactly one .json job template when not using inline json.","Treat keytab/xml resources as auxiliary; never rely on resourceList[0] as the job file.","Validate task params in the UI before saving workflows."],"tags":["datax","missing-config","validation"],"backgroundTag":"missing-required-config-field","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"}