{"record":{"id":"49dcb395bedd250e","repo":"apache/dolphinscheduler","slug":"get-more-than-one-datasource-by-name-s","errorCode":null,"errorMessage":"Get more than one datasource by name %s","messagePattern":"Get more than one datasource by name (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/python/PythonGateway.java","lineNumber":502,"sourceCode":"     */\n    public DataSource getDatasource(String datasourceName, String type) {\n\n        List<DataSource> dataSourceList = dataSourceDao.queryDataSourceByName(datasourceName);\n        if (dataSourceList == null || dataSourceList.isEmpty()) {\n            String msg = String.format(\"Can not find any datasource by name %s\", datasourceName);\n            log.error(msg);\n            throw new IllegalArgumentException(msg);\n        }\n\n        List<DataSource> dataSourceListMatchType = dataSourceList.stream()\n                .filter(dataSource -> type == null || StringUtils.equalsIgnoreCase(dataSource.getType().name(), type))\n                .collect(Collectors.toList());\n\n        log.info(\"Get the datasource list match the type are: {}\", dataSourceListMatchType);\n        if (dataSourceListMatchType.size() > 1) {\n            String msg = String.format(\"Get more than one datasource by name %s\", datasourceName);\n            log.error(msg);\n            throw new IllegalArgumentException(msg);\n        }\n\n        return dataSourceListMatchType.stream().findFirst().orElseThrow(() -> {\n            String msg = String.format(\"Can not find any datasource by name %s and type %s\", datasourceName, type);\n            log.error(msg);\n            return new IllegalArgumentException(msg);\n        });\n    }\n\n    /**\n     * Get workflow object by given workflow name. It returns map contain workflow id, name, code.\n     * Useful in Python API create sub workflow task which need workflow information.\n     *\n     * @param userName     user who create or update schedule\n     * @param projectName  project name which workflow belongs to\n     * @param workflowName workflow name\n     */\n    public Map<String, Object> getWorkflowInfo(String userName, String projectName,","sourceCodeStart":484,"sourceCodeEnd":520,"githubUrl":"https://github.com/apache/dolphinscheduler/blob/02eac45a1b6676e639fcbfb4be2243de5771b05d/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/python/PythonGateway.java#L484-L520","documentation":"After filtering datasources matching the requested name and (optional) type, getDatasource requires a unique match; if more than one datasource shares the name (and type filter), it throws IllegalArgumentException because it cannot decide which one to return. DolphinScheduler historically allowed duplicate datasource names, so this is an ambiguity error, not a lookup failure.","triggerScenarios":"Two or more datasources exist with the same name (optionally the type parameter passed to getDatasource is null or does not discriminate) and the Python gateway calls getDatasource(datasourceName, type).","commonSituations":"Datasource names duplicated across tenants/users; old DolphinScheduler instances where name uniqueness was not enforced; calling getDatasource without the type argument while same-named datasources of different types exist.","solutions":["Rename or delete the duplicate datasource in the Data Source center so the name is unique","Pass the exact type (e.g. MYSQL) as the type argument so only one match remains","Update pydolphinscheduler scripts to reference the uniquely renamed datasource","Upgrade to a DolphinScheduler version enforcing datasource name uniqueness and deduplicate existing rows"],"exampleFix":"// before\ndataSource ds = pythonGateway.getDatasource(\"my-db\", null);\n// after\ndataSource ds = pythonGateway.getDatasource(\"my-db\", \"MYSQL\");","handlingStrategy":"validation","validationCode":"long count = dataSourceDao.queryDataSourceByName(name).stream()\n    .filter(ds -> type == null || ds.getType().name().equalsIgnoreCase(type))\n    .count();\nif (count != 1) {\n    throw new IllegalStateException(\"Expected exactly 1 datasource named \" + name + \", found \" + count);\n}","typeGuard":null,"tryCatchPattern":"try {\n    DataSource ds = pythonGateway.getDatasource(name, type);\n} catch (IllegalArgumentException e) {\n    log.error(\"Ambiguous datasource name; pass an explicit type or deduplicate\", e);\n}","preventionTips":["Enforce unique datasource names; treat duplicates as admin errors","Always pass the datasource type when calling getDatasource","Periodically audit the t_ds_datasource table for duplicate names"],"tags":["python-api","datasource","ambiguity"],"backgroundTag":"invalid-argument-value","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"}