{"record":{"id":"bb54546042f6beac","repo":"apache/druid","slug":"s3-external-table-defines-the-s-property-the-tab","errorCode":null,"errorMessage":"S3 external table defines the %s property. The table function must provide the %s parameter","messagePattern":"S3 external table defines the (.+?) property\\. The table function must provide the (.+?) parameter","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions-core/s3-extensions/src/main/java/org/apache/druid/catalog/model/table/S3InputSourceDefn.java","lineNumber":318,"sourceCode":"    return new PartialTableFunction(table, params);\n  }\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\n    // If a bucket parameter is provided, user provides the objects. Else, use the\n    // catalog input source definition.\n    final String bucket = table.resolvedTable().stringProperty(BUCKET_PROPERTY);\n    if (bucket != null) {\n      List<String> paths = CatalogUtils.getStringArray(args, PATHS_PARAMETER);\n      if (CollectionUtils.isNullOrEmpty(paths)) {\n        throw new IAE(\n            \"S3 external table defines the %s property. The table function must provide the %s parameter\",\n            BUCKET_PROPERTY,\n            PATHS_PARAMETER\n        );\n      }\n      List<CloudObjectLocation> objects = new ArrayList<>();\n      for (String obj : paths) {\n        objects.add(new CloudObjectLocation(bucket, obj));\n      }\n      sourceMap.put(OBJECTS_FIELD, objects);\n    }\n\n    applySecurityParams(sourceMap, args);\n    return convertPartialFormattedTable(table, args, columns, sourceMap);\n  }\n}\n","sourceCodeStart":300,"sourceCodeEnd":335,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/extensions-core/s3-extensions/src/main/java/org/apache/druid/catalog/model/table/S3InputSourceDefn.java#L300-L335","documentation":"This IllegalArgumentException is thrown in convertCompletedTable when the catalog S3 external table definition includes a 'bucket' property, which means the user is expected to supply the objects, but the table function call did not provide the 'paths' parameter (or provided an empty list). The catalog property shifts responsibility for object selection from the catalog definition to the caller, and the caller did not fulfill it.","triggerScenarios":"Querying a catalog-defined S3 external table whose resolved table has a bucketProperty set, via a table function call whose args contain no non-empty value for the 'paths' parameter (CatalogUtils.getStringArray returns null or empty).","commonSituations":"Calling a catalog S3 table with SELECT * without the table function arguments; passing paths as the wrong type (single string vs array) so getStringArray sees it as empty; the catalog admin added the bucket property, changing the required call signature.","solutions":["Supply a non-empty 'paths' parameter (array of object keys) in the table function call.","Check the catalog table definition: if bucketProperty is set, paths are mandatory at call time.","Ensure 'paths' is passed as a string array, not a scalar or JSON string.","Alternatively, redefine the catalog table with URIs/prefixes in the input source instead of bucket + per-call paths."],"exampleFix":"// before\nSELECT * FROM TABLE(EXTERN('my_s3_table'))\n// after\nSELECT * FROM TABLE(EXTERN('my_s3_table', 'paths' => ARRAY['data/2024/part-1.json','data/2024/part-2.json']))","handlingStrategy":"validation","validationCode":"if (catalogTable.hasProperty(\"bucket\")) {\n  List<String> paths = args.get(\"paths\");\n  if (paths == null || paths.isEmpty()) {\n    throw new IllegalArgumentException(\"Catalog table defines 'bucket'; pass a non-empty 'paths' array to the table function\");\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Read the catalog table definition to know which parameters the function call must supply","Pass paths as a proper string array, not a scalar string","When an admin adds bucketProperty to a catalog table, update all query templates that use it"],"tags":["validation","catalog","s3","missing-argument"],"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-14T05:17:10.506Z"}