{"record":{"id":"9ec74679017893a2","repo":"apache/pulsar","slug":"field-name-must-be-an-iterable-but-was-a-fiel","errorCode":null,"errorMessage":"Field ${name} must be an Iterable but was a ${field.getClass()}","messagePattern":"Field (.+?) must be an Iterable but was a (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-config-validation/src/main/java/org/apache/pulsar/config/validation/ConfigValidationUtils.java","lineNumber":92,"sourceCode":"        return new NestableFieldValidator() {\n            @Override\n            public void validateField(String pd, String name, Object field)\n                    throws IllegalArgumentException {\n\n                if (field == null) {\n                    if (notNull) {\n                        throw new IllegalArgumentException(\"Field \" + name + \" must not be null\");\n                    } else {\n                        return;\n                    }\n                }\n                if (field instanceof Iterable) {\n                    for (Object e : (Iterable) field) {\n                        validator.validateField(pd + \"Each element of the list \", name, e);\n                    }\n                    return;\n                }\n                throw new IllegalArgumentException(\n                        \"Field \" + name + \" must be an Iterable but was a \" + field.getClass());\n            }\n        };\n    }\n\n    /**\n     * Returns a new NestableFieldValidator for a Map of key to val.\n     *\n     * @param key     the Class of keys in the map\n     * @param val     the Class of values in the map\n     * @param notNull whether or not a value of null is valid\n     * @return a NestableFieldValidator for a Map of key to val\n     */\n    public static NestableFieldValidator mapFv(Class<?> key, Class<?> val,\n                                               boolean notNull) {\n        return mapFv(fv(key, false), fv(val, false), notNull);\n    }\n","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-config-validation/src/main/java/org/apache/pulsar/config/validation/ConfigValidationUtils.java#L74-L110","documentation":"The list-validator NestableFieldValidator throws IllegalArgumentException when the field is non-null but is not an Iterable, i.e. a list-typed config field was given a scalar value. Each element is otherwise validated with the nested validator.","triggerScenarios":"A list-typed config property set to a single scalar (String or Number) instead of a collection — common when using properties files where list syntax collapses to one string, or YAML where the value was not written as a list.","commonSituations":"Writing 'servers=zk1,zk2' in a properties file where the validator expects an actual List/Iterable object; YAML 'servers: zk1' instead of a dash list; programmatic config built with a String instead of List<String>.","solutions":["Provide the value as a real collection (YAML dash list or JSON array)","If the framework supports delimited strings, split into a List before validation (e.g. Arrays.asList(value.split(\",\")))","Fix programmatic construction to assign List<String> (or the declared Iterable type) rather than String"],"exampleFix":"# before\nservers: zk1,zk2\n# after\nservers:\n  - zk1\n  - zk2","handlingStrategy":"type-guard","validationCode":"// before validateConfig\nObject servers = conf.get(\"servers\");\nif (!(servers instanceof java.util.List)) {\n    if (servers instanceof String) conf.put(\"servers\", java.util.Arrays.asList(((String) servers).split(\",\")));\n    else throw new IllegalStateException(\"servers must be a list\");\n}","typeGuard":"static boolean isList(Object o) { return o instanceof java.util.List; }","tryCatchPattern":"try {\n    ConfigValidation.validateConfig(conf);\n} catch (IllegalArgumentException e) {\n    throw new IllegalStateException(\"List field given scalar value: \" + e.getMessage(), e);\n}","preventionTips":["Write lists as YAML dash items or JSON arrays","Split comma-separated properties strings into List before validation","Keep programmatic builders typed (List<String>) rather than String"],"tags":["config-validation","type-mismatch","iterable"],"backgroundTag":"config-type-mismatch","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}