{"record":{"id":"dbd872b17b69a8e7","repo":"apache/druid","slug":"when-a-local-external-table-is-used-with-a-table-f","errorCode":null,"errorMessage":"When a local external table is used with a table function, %s must be set","messagePattern":"When a local external table is used with a table function, (.+?) must be set","errorType":"validation","errorClass":"IAE","httpStatus":null,"severity":"error","filePath":"server/src/main/java/org/apache/druid/catalog/model/table/LocalInputSourceDefn.java","lineNumber":216,"sourceCode":"  }\n\n  @Override\n  protected ExternalTableSpec convertCompletedTable(\n      final ResolvedExternalTable table,\n      final Map<String, Object> args,\n      final List<ColumnSpec> columns\n  )\n  {\n    final Map<String, Object> sourceMap = new HashMap<>(table.inputSourceMap);\n    final boolean hasFiles = !CollectionUtils.isNullOrEmpty(CatalogUtils.safeGet(sourceMap, FILES_FIELD, List.class));\n    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","sourceCodeStart":198,"sourceCodeEnd":234,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/server/src/main/java/org/apache/druid/catalog/model/table/LocalInputSourceDefn.java#L198-L234","documentation":"When a local external table's stored input source has no files list, the table must define a baseDir property, because any table-function arguments (files/filter) are resolved relative to that directory. If the stored table lacks baseDir, convertCompletedTable throws this IAE naming the missing field.","triggerScenarios":"Invoking a table function on a local external table whose inputSourceMap has neither files nor baseDir set (e.g. created without validation or via a partial definition).","commonSituations":"Hand-edited or imported table specs missing baseDir; tables created before validation rules tightened; programmatically built definitions that only set type and format.","solutions":["Add a baseDir property to the table definition","Add a files property to the table definition instead","Recreate the table definition through the catalog API so validation runs"],"exampleFix":"// before\n{\"type\":\"local\"}\n// after\n{\"type\":\"local\",\"baseDir\":\"/data/incoming\"}","handlingStrategy":"validation","validationCode":"// Java\nMap<String,Object> src = table.inputSourceMap;\nboolean ok = !CollectionUtils.isNullOrEmpty((List<?>) src.getOrDefault(\"files\", List.of()))\n          || !Strings.isNullOrEmpty((String) src.get(\"baseDir\"));\nif (!ok) throw new IllegalArgumentException(\"table needs files or baseDir property\");","typeGuard":null,"tryCatchPattern":"try { fn.call(args); } catch (IAE e) { if (e.getMessage().contains(\"must be set\")) { /* set baseDir on the table definition */ } else throw e; }","preventionTips":["When defining local tables, always set baseDir (required for function use)","Validate table specs with ResolvedExternalTable.validate before publishing","Avoid hand-editing table JSON — use the catalog API"],"tags":["druid-catalog","validation","local-input-source","table-definition"],"backgroundTag":"missing-required-config-field","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"}