{"record":{"id":"3f77262a2cf7c7b3","repo":"elastic/elasticsearch","slug":"field-of-type-cannot-be-cast-to","errorCode":null,"errorMessage":"field [{}] of type [{}] cannot be cast to [{}]","messagePattern":"field \\[(.+?)\\] of type \\[(.+?)\\] cannot be cast to \\[(.+?)\\]","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/AbstractStringProcessor.java","lineNumber":87,"sourceCode":"                    throw new IllegalArgumentException(\n                        \"value [\"\n                            + value\n                            + \"] of type [\"\n                            + value.getClass().getName()\n                            + \"] in list field [\"\n                            + field\n                            + \"] cannot be cast to [\"\n                            + String.class.getName()\n                            + \"]\"\n                    );\n                }\n            }\n            newValue = newList;\n        } else {\n            if (val instanceof String string) {\n                newValue = process(string);\n            } else {\n                throw new IllegalArgumentException(\n                    \"field [\" + field + \"] of type [\" + val.getClass().getName() + \"] cannot be cast to [\" + String.class.getName() + \"]\"\n                );\n            }\n\n        }\n\n        document.setFieldValue(targetField, newValue);\n        return document;\n    }\n\n    protected abstract T process(String value);\n\n    abstract static class Factory implements Processor.Factory {\n        final String processorType;\n\n        protected Factory(String processorType) {\n            this.processorType = processorType;\n        }","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/modules/ingest-common/src/main/java/org/elasticsearch/ingest/common/AbstractStringProcessor.java#L69-L105","documentation":"IllegalArgumentException from AbstractStringProcessor when the source field is a scalar (non-list) value that is not a String — e.g. a number, boolean, or object. The processor requires a string input and will not implicitly coerce.","triggerScenarios":"The configured field holds a single non-string scalar; the final else branch in execute throws. Example: field 'port' = 9200 fed to an uppercase processor.","commonSituations":"Numeric/boolean fields mistakenly targeted by a string processor; schema drift changing a field's type; mappings inferred the field as long/boolean.","solutions":["Insert a convert processor (type: string) before this processor","Target a field that is actually a string","Use a script processor for custom coercion logic"],"exampleFix":"// before\n{\"processors\":[{\"uppercase\":{\"field\":\"port\"}}]} // port=9200\n// after\n{\"processors\":[{\"convert\":{\"field\":\"port\",\"type\":\"string\"}},{\"uppercase\":{\"field\":\"port\"}}]}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"// Only route scalar string fields to string processors:\nboolean isStringScalar(Object v) { return v instanceof String; }","tryCatchPattern":"try { processor.execute(doc); }\ncatch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"cannot be cast to\")) { convert(doc, field, String.class); processor.execute(doc); }\n    else throw e;\n}","preventionTips":["Use a convert processor to coerce numeric/boolean fields to string first","Review dynamic mappings that may have typed a target field as non-string","Target only known-string fields with string processors"],"tags":["ingest","string-processor","type-cast","scalar"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}