{"record":{"id":"a76cfe7b9dbfe9e1","repo":"apache/druid","slug":"for-a-local-input-source-set-either-s-or-s","errorCode":null,"errorMessage":"For a local input source, set either %s or %s","messagePattern":"For a local input source, set either (.+?) or (.+?)","errorType":"validation","errorClass":"IAE","httpStatus":null,"severity":"error","filePath":"server/src/main/java/org/apache/druid/catalog/model/table/LocalInputSourceDefn.java","lineNumber":227,"sourceCode":"    if (hasFiles) {\n      if (!args.isEmpty()) {\n        throw new IAE(\"The local input source has a file list: do not provide other arguments\");\n      }\n    } else {\n      final String baseDir = CatalogUtils.getString(sourceMap, BASE_DIR_FIELD);\n      if (Strings.isNullOrEmpty(baseDir)) {\n        throw new IAE(\n            \"When a local external table is used with a table function, %s must be set\",\n            BASE_DIR_FIELD\n        );\n      }\n      final boolean hasFilter = !Strings.isNullOrEmpty(CatalogUtils.getString(sourceMap, FILTER_FIELD));\n      final List<String> filesParam = CatalogUtils.getStringArray(args, FILES_PARAMETER);\n      final boolean hasFilesParam = !CollectionUtils.isNullOrEmpty(filesParam);\n      final String filterParam = CatalogUtils.getString(args, FILTER_PARAMETER);\n      final boolean hasFilterParam = !Strings.isNullOrEmpty(filterParam);\n      if (!hasFilter && !hasFilesParam && !hasFilterParam) {\n        throw new IAE(\n            \"For a local input source, set either %s or %s\",\n            FILES_PARAMETER,\n            FILTER_PARAMETER\n        );\n      }\n      if (hasFilesParam) {\n        // Special workaround: if the user provides a base dir, and files, convert\n        // the files to be absolute paths relative to the base dir. Then, remove\n        // the baseDir, since the Druid input source does not allow both a baseDir\n        // and a list of files.\n        sourceMap.remove(FILTER_FIELD);\n        sourceMap.remove(BASE_DIR_FIELD);\n        sourceMap.put(FILES_FIELD, absolutePath(baseDir, filesParam));\n      } else if (filterParam != null) {\n        sourceMap.put(FILTER_FIELD, filterParam);\n      }\n    }\n    return convertPartialFormattedTable(table, args, columns, sourceMap);","sourceCodeStart":209,"sourceCodeEnd":245,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/server/src/main/java/org/apache/druid/catalog/model/table/LocalInputSourceDefn.java#L209-L245","documentation":"A baseDir-based local external table used via a table function must receive at least one of: a stored filter property, a files function argument, or a filter function argument. Otherwise there is no way to select which files under baseDir to read, so convertCompletedTable throws this IAE.","triggerScenarios":"Calling TABLE(baseDirTable) with no arguments where the table defines only baseDir (no filter) — no files or filter argument passed.","commonSituations":"Calling a table function with just format arguments and forgetting file selection; assuming the baseDir alone reads all files; older clients that predate the files/filter function parameters.","solutions":["Pass a files argument: TABLE(t, FILES => ARRAY['a.json'])","Pass a filter argument: TABLE(t, FILTER => '*.json')","Set a filter property on the table definition itself"],"exampleFix":"// before\nSELECT * FROM TABLE(localTable(FORMAT => 'json'))\n// after\nSELECT * FROM TABLE(localTable(FORMAT => 'json', FILTER => '*.json'))","handlingStrategy":"validation","validationCode":"// Java\nboolean storedFilter = hasNonEmpty(table.inputSourceMap.get(\"filter\"));\nif (!storedFilter && !hasParam(args,\"files\") && !hasParam(args,\"filter\"))\n  throw new IllegalArgumentException(\"pass FILES or FILTER to the table function\");","typeGuard":null,"tryCatchPattern":"try { fn.call(args); } catch (IAE e) { if (e.getMessage().contains(\"set either\")) { args.put(\"filter\",\"*.json\"); fn.call(args); } else throw e; }","preventionTips":["baseDir alone selects nothing — always supply files or filter at some layer","Set a default filter property on the table if the same pattern is always used","Include file selection in SQL-generation checklists"],"tags":["druid-catalog","validation","table-function","local-input-source"],"backgroundTag":"missing-required-argument","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}