{"record":{"id":"ecc441636cc21788","repo":"elastic/elasticsearch","slug":"field-is-null-cannot-loop-over-its-elements","errorCode":null,"errorMessage":"field [{}] is null, cannot loop over its elements.","messagePattern":"field \\[(.+?)\\] is null, cannot loop over its elements\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/ForEachProcessor.java","lineNumber":69,"sourceCode":"        this.field = field;\n        this.processor = processor;\n        this.ignoreMissing = ignoreMissing;\n    }\n\n    boolean isIgnoreMissing() {\n        return ignoreMissing;\n    }\n\n    @Override\n    public IngestDocument execute(IngestDocument ingestDocument) throws Exception {\n        assert isAsync() == false;\n\n        Object o = ingestDocument.getFieldValue(field, Object.class, ignoreMissing);\n        if (o == null) {\n            if (ignoreMissing) {\n                return ingestDocument;\n            } else {\n                throw new IllegalArgumentException(\"field [\" + field + \"] is null, cannot loop over its elements.\");\n            }\n        } else if (o instanceof Map<?, ?> map) {\n            return iterateMap(ingestDocument, map);\n        } else if (o instanceof List<?> list) {\n            return iterateList(ingestDocument, list);\n        } else {\n            throw new IllegalArgumentException(\n                \"field [\" + field + \"] of type [\" + o.getClass().getName() + \"] cannot be cast to a \" + \"list or map\"\n            );\n        }\n    }\n\n    private IngestDocument iterateMap(IngestDocument document, Map<?, ?> map) throws Exception {\n        var newValues = Maps.newHashMapWithExpectedSize(map.size());\n        for (Map.Entry<?, ?> e : map.entrySet()) {\n            String key = (String) e.getKey();\n            Object previousKey = document.getIngestMetadata().put(\"_key\", key);\n            Object value = e.getValue();","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/ForEachProcessor.java#L51-L87","documentation":"Thrown by ForEachProcessor.execute when the configured field resolves to null and ignoreMissing is false. The processor cannot iterate over a null value, so it refuses unless the user explicitly opted into ignoring missing fields. This is an IllegalArgumentException documenting a pipeline/data mismatch.","triggerScenarios":"A foreach ingest processor runs on a document where the target field is absent or explicitly null, and the processor was created with ignore_missing=false (the default).","commonSituations":"Documents with sparse fields, pipeline author forgot \"ignore_missing\": true, upstream processor dropped the field, or field path typo means the field never exists.","solutions":["Add \"ignore_missing\": true to the foreach processor if null fields are expected and should skip.","Ensure an upstream set/rename processor populates the field before foreach runs.","Verify the field path in the processor matches the document schema (no typos, correct dot-path)."],"exampleFix":"// before\n{\"foreach\": {\"field\": \"tags\", \"processor\": {...}}}\n// after\n{\"foreach\": {\"field\": \"tags\", \"ignore_missing\": true, \"processor\": {...}}}","handlingStrategy":"validation","validationCode":"// before foreach, assert field is present or ignore_missing is set\nif (processor.ignoreMissing == false && doc.hasField(processor.field) == false) {\n    // skip doc or fail pipeline definition\n}","typeGuard":"static boolean canForeach(IngestDocument doc, String field, boolean ignoreMissing) {\n    if (ignoreMissing) return true;\n    Object v = doc.getFieldValue(field, Object.class, true);\n    return v != null;\n}","tryCatchPattern":"try {\n    processor.execute(doc);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"is null, cannot loop\")) {\n        // route to dead-letter or skip\n    } else throw e;\n}","preventionTips":["Default ignore_missing=true on foreach for fields that may be absent.","Document the field schema upstream of foreach so authors know if it's nullable.","Add a pipeline simulation (simulate API) with representative docs including null-field cases before deploying."],"tags":["ingest","foreach","null-field","configuration"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}