{"record":{"id":"968aaf3b0df6fae7","repo":"apache/druid","slug":"s-property-must-be-provided","errorCode":null,"errorMessage":"[%s] property must be provided","messagePattern":"\\[(.+?)\\] property must be provided","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"server/src/main/java/org/apache/druid/catalog/model/table/FormattedInputSourceDefn.java","lineNumber":129,"sourceCode":"          throw new ISE(\n              \"Format [%s], property [%s] of class [%s] conflicts with another format property of class [%s]\",\n              format.typeValue(),\n              prop.name(),\n              prop.type().sqlName(),\n              existing.type().sqlName()\n          );\n        }\n      }\n    }\n    return CatalogUtils.concatLists(properties, toAdd);\n  }\n\n  @Override\n  protected InputFormat convertTableToFormat(ResolvedExternalTable table)\n  {\n    final String formatTag = CatalogUtils.getString(table.inputFormatMap, InputFormat.TYPE_PROPERTY);\n    if (formatTag == null) {\n      throw new IAE(\"[%s] property must be provided\", InputFormat.TYPE_PROPERTY);\n    }\n    final InputFormatDefn formatDefn = formats.get(formatTag);\n    if (formatDefn == null) {\n      throw new IAE(\n          \"Format type [%s] for property [%s] is not valid\",\n          formatTag,\n          InputFormat.TYPE_PROPERTY\n      );\n    }\n    return formatDefn.convertFromTable(table);\n  }\n\n  @Override\n  protected InputFormat convertArgsToFormat(Map<String, Object> args, List<ColumnSpec> columns, ObjectMapper jsonMapper)\n  {\n    final String formatTag = CatalogUtils.getString(args, FORMAT_PARAMETER);\n    if (formatTag == null) {\n      throw new IAE(\"Must provide a value for the [%s] parameter\", FORMAT_PARAMETER);","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/server/src/main/java/org/apache/druid/catalog/model/table/FormattedInputSourceDefn.java#L111-L147","documentation":"FormattedInputSourceDefn.convertTableToFormat reads the format 'type' property from the table's inputFormatMap; if it is absent the format cannot be resolved, so this IAE is thrown naming the missing property (InputFormat.TYPE_PROPERTY).","triggerScenarios":"Converting a partial formatted table (convertPartialFormattedTable) whose inputFormatMap exists but lacks the 'type' key, or where CatalogUtils.getString returns null for it.","commonSituations":"Specs with format properties but no {\"type\": ...} tag; JSON written by hand that nests properties above the type field; partial updates that replace the format map with properties only.","solutions":["Add the \"type\" property to the inputFormatMap, e.g. {\"type\":\"csv\"}.","Ensure format properties are nested under the format object, not alongside it.","Recreate the spec via the UI so the format type is set.","Validate the inputFormatMap contains InputFormat.TYPE_PROPERTY before calling convert."],"exampleFix":"// before\n\"inputFormat\": {\"skipHeaderRows\": 0}\n// after\n\"inputFormat\": {\"type\": \"csv\", \"skipHeaderRows\": 0}","handlingStrategy":"validation","validationCode":"Map<String,Object> fmt = table.getInputFormatMap();\nif (fmt == null || fmt.get(\"type\") == null) throw new IllegalArgumentException(\"inputFormat.type is required\");","typeGuard":"boolean hasFormatType(Map<String,Object> m) { return m != null && m.get(\"type\") instanceof String && !((String) m.get(\"type\")).isEmpty(); }","tryCatchPattern":"try { format = defn.convertTableToFormat(table); } catch (IAE e) { if (e.getMessage().contains(\"property must be provided\")) { fixFormatMap(table); format = defn.convertTableToFormat(table); } }","preventionTips":["Always include \"type\" inside the inputFormat object","Nest format properties under the format map, not beside it","Validate specs locally before conversion","Recreate specs via UI to guarantee the type field"],"tags":["druid","input-format","missing-property"],"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"}