{"record":{"id":"9d8272889601e85f","repo":"apache/dolphinscheduler","slug":"unbound-test-data-source","errorCode":null,"errorMessage":"unbound test data source","messagePattern":"unbound test data source","errorType":"validation","errorClass":"TaskException","httpStatus":null,"severity":"error","filePath":"dolphinscheduler-task-plugin/dolphinscheduler-task-sql/src/main/java/org/apache/dolphinscheduler/plugin/task/sql/SqlTask.java","lineNumber":109,"sourceCode":"    private static final int QUERY_LIMIT = 10000;\n\n    private final SQLTaskExecutionContext sqlTaskExecutionContext;\n\n    private final DbType dbType;\n\n    private Connection sessionConnection;\n    private Statement sessionStatement;\n\n    public SqlTask(TaskExecutionContext taskRequest) {\n        super(taskRequest);\n        this.taskExecutionContext = taskRequest;\n        this.sqlParameters = JSONUtils.parseObject(taskExecutionContext.getTaskParams(), SqlParameters.class);\n        log.info(\"Initialize sql task parameter {}\", JSONUtils.toPrettyJsonString(sqlParameters));\n        if (sqlParameters == null || !sqlParameters.checkParameters()) {\n            throw new TaskException(\"sql task params is not valid\");\n        }\n        if (this.sqlParameters.getDatasource() == 0) {\n            throw new TaskException(\"unbound test data source\");\n        }\n\n        sqlTaskExecutionContext =\n                sqlParameters.generateExtendedContext(taskExecutionContext.getResourceParametersHelper());\n        dbType = DbType.valueOf(sqlParameters.getType());\n    }\n\n    @Override\n    public AbstractParameters getParameters() {\n        return sqlParameters;\n    }\n\n    @Override\n    public void handle(TaskCallBack taskCallBack) throws TaskException {\n        log.info(\"Full sql parameters: {}\", sqlParameters);\n        log.info(\n                \"sql type : {}, datasource : {}, sql : {} , localParams : {},showType : {},connParams : {},varPool : {} ,query max result limit  {}\",\n                sqlParameters.getType(),","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/apache/dolphinscheduler/blob/02eac45a1b6676e639fcbfb4be2243de5771b05d/dolphinscheduler-task-plugin/dolphinscheduler-task-sql/src/main/java/org/apache/dolphinscheduler/plugin/task/sql/SqlTask.java#L91-L127","documentation":"Right after the params-validity check, the SqlTask constructor rejects tasks whose sqlParameters.getDatasource() == 0, throwing TaskException(\"unbound test data source\"). Datasource id 0 means no datasource was bound to the node, so the task has no target database. Despite the message wording, this is the generic unbound-datasource check for every SQL task.","triggerScenarios":"A SQL task node was created/saved without selecting a datasource (datasourceId defaults to 0); a workflow definition was imported/API-submitted with datasource absent or 0 in taskParams.","commonSituations":"Datasource referenced by the task was deleted and a re-saved template lost the binding; programmatic workflow creation omitted the datasource field; copying a task between projects where the datasource id does not exist in the target project.","solutions":["Open the SQL task node and select a valid datasource from the dropdown, then re-save the workflow","When building workflows via API/SDK, explicitly set datasource to the numeric id of an existing datasource in taskParams","Verify the datasource id exists for the project (datasources API / t_ds_datasource) if importing definitions across environments"],"exampleFix":"// before\n{\"taskType\":\"SQL\",\"taskParams\":{\"type\":\"MYSQL\",\"datasource\":0,\"sql\":\"select 1\"}}\n// after\n{\"taskType\":\"SQL\",\"taskParams\":{\"type\":\"MYSQL\",\"datasource\":3,\"sql\":\"select 1\"}}","handlingStrategy":"validation","validationCode":"SqlParameters p = JSONUtils.parseObject(taskParams, SqlParameters.class);\nif (p == null || p.getDatasource() == 0) {\n    throw new IllegalArgumentException(\"sql task has no datasource bound\");\n}","typeGuard":"boolean hasDatasource(String json) {\n    SqlParameters p = JSONUtils.parseObject(json, SqlParameters.class);\n    return p != null && p.getDatasource() > 0;\n}","tryCatchPattern":null,"preventionTips":["Always select a datasource in the SQL node before saving; rely on the UI's required-field check","When creating workflows via API/SDK, set datasource to an existing datasource id for the project","Check datasource existence after cross-project copies or environment migrations"],"tags":["sql","datasource","missing-binding"],"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-14T00:17:10.932Z"}