From 457fa817658685b0b217fdd9ffa3163b529be495 Mon Sep 17 00:00:00 2001 From: David Kilfoyle Date: Fri, 24 Oct 2025 14:54:41 -0400 Subject: [PATCH 1/5] Painless docs overhaul (troubleshooting) --- ...painless-array-list-manipulation-errors.md | 161 ++++++++++ .../painless-date-math-errors.md | 108 +++++++ .../elasticsearch/painless-field-not-found.md | 244 +++++++++++++++ .../painless-ingest-pipeline-failures.md | 137 +++++++++ .../painless-null-pointer-exceptions.md | 166 ++++++++++ ...ainless-regex-pattern-matching-failures.md | 120 ++++++++ .../painless-runtime-field-exceptions.md | 161 ++++++++++ .../painless-sandbox-limitations.md | 139 +++++++++ ...ainless-script-score-calculation-errors.md | 185 ++++++++++++ .../elasticsearch/painless-scripting.md | 23 ++ .../elasticsearch/painless-subfield-access.md | 283 ++++++++++++++++++ .../painless-type-casting-issues.md | 212 +++++++++++++ troubleshoot/toc.yml | 13 + 13 files changed, 1952 insertions(+) create mode 100644 troubleshoot/elasticsearch/painless-array-list-manipulation-errors.md create mode 100644 troubleshoot/elasticsearch/painless-date-math-errors.md create mode 100644 troubleshoot/elasticsearch/painless-field-not-found.md create mode 100644 troubleshoot/elasticsearch/painless-ingest-pipeline-failures.md create mode 100644 troubleshoot/elasticsearch/painless-null-pointer-exceptions.md create mode 100644 troubleshoot/elasticsearch/painless-regex-pattern-matching-failures.md create mode 100644 troubleshoot/elasticsearch/painless-runtime-field-exceptions.md create mode 100644 troubleshoot/elasticsearch/painless-sandbox-limitations.md create mode 100644 troubleshoot/elasticsearch/painless-script-score-calculation-errors.md create mode 100644 troubleshoot/elasticsearch/painless-scripting.md create mode 100644 troubleshoot/elasticsearch/painless-subfield-access.md create mode 100644 troubleshoot/elasticsearch/painless-type-casting-issues.md diff --git a/troubleshoot/elasticsearch/painless-array-list-manipulation-errors.md b/troubleshoot/elasticsearch/painless-array-list-manipulation-errors.md new file mode 100644 index 0000000000..a1802c0821 --- /dev/null +++ b/troubleshoot/elasticsearch/painless-array-list-manipulation-errors.md @@ -0,0 +1,161 @@ +--- +navigation_title: Array/list manipulation errors +--- + +# Troubleshoot array/list manipulation errors in Painless + +Follow these guidelines to avoid array access errors in your Painless script. + +## Array index\_out\_of\_bounds\_exception + +Array index out of bounds exceptions occur when a script tries to access an element at a position that does not exist in the array. For example, if an array has two elements, trying to access a third element will trigger this exception. + +### Sample error + +```json +{ + "error": { + "root_cause": [ + { + "type": "index_out_of_bounds_exception", + "reason": "index_out_of_bounds_exception: Index 2 out of bounds for length 2" + } + ], + "type": "search_phase_execution_exception", + "reason": "all shards failed", + "phase": "query", + "grouped": true, + "failed_shards": [ + { + "shard": 0, + "index": "blog_posts", + "node": "hupWdkj_RtmThGjNUiIt_w", + "reason": { + "type": "script_exception", + "reason": "runtime error", + "script_stack": [ + "java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:100)", + "java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:106)", + "java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:302)", + "java.base/java.util.Objects.checkIndex(Objects.java:365)", + "java.base/java.util.ArrayList.get(ArrayList.java:428)", + """return keywords[2].toUpperCase(); + """, + " ^---- HERE" + ], + "script": " ...", + "lang": "painless", + "position": { + "offset": 76, + "start": 61, + "end": 105 + }, + "caused_by": { + "type": "index_out_of_bounds_exception", + "reason": "index_out_of_bounds_exception: Index 2 out of bounds for length 2" + } + } + } + ], + "caused_by": { + "type": "index_out_of_bounds_exception", + "reason": "index_out_of_bounds_exception: Index 2 out of bounds for length 2" + } + }, + "status": 400 +} +``` + +### Problematic code + +```json +{ + "aggs": { + "third_tag_stats": { + "terms": { + "script": { + "source": """ + def keywords = params._source.tags; + + return keywords[2].toUpperCase(); + """, + "lang": "painless" + } + } + } + } +} +``` + +### Root cause + +The error occurs because the script tries to access index 2 (the third element) in an array that only has two elements (indices 0, 1). Arrays in Painless are zero-indexed, so accessing an index greater than or equal to the array size causes an exception. + +### Solution: Check array bounds before accessing + +Always verify array size before accessing specific indices: + +```json +GET blog_posts/_search +{ + "size": 0, + "aggs": { + "third_tag_stats": { + "terms": { + "script": { + "source": """ + def keywords = params._source.tags; + + if (keywords.size() > 2) { + return keywords[2].toUpperCase(); + } else { + return "NO_THIRD_TAG"; + } + """, + "lang": "painless" + } + } + } + } +} +``` + +### Sample document + +```json +POST blog_posts/_doc +{ + "title": "Getting Started with Elasticsearch", + "content": "Learn the basics...", + "tags": ["elasticsearch", "tutorial"] +} +``` + +### Results + +```json +{ + ..., + "hits": { + ... + }, + "aggregations": { + "third_tag_stats": { + "doc_count_error_upper_bound": 0, + "sum_other_doc_count": 0, + "buckets": [ + { + "key": "NO_THIRD_TAG", + "doc_count": 1 + } + ] + } + } +} +``` + +### Notes + +* **Array bounds:** Always check array size before accessing specific indices. +* **Zero-indexed:** Remember that arrays start at index 0, so size() \- 1 is the last valid index. +* **Empty arrays:** Handle cases where arrays might be completely empty (size() \== 0). diff --git a/troubleshoot/elasticsearch/painless-date-math-errors.md b/troubleshoot/elasticsearch/painless-date-math-errors.md new file mode 100644 index 0000000000..e51b28559c --- /dev/null +++ b/troubleshoot/elasticsearch/painless-date-math-errors.md @@ -0,0 +1,108 @@ +--- +navigation_title: Date math errors +--- + +# Troubleshoot date math errors in Painless + +Follow these guidelines to avoid [date](elasticsearch://reference/scripting-languages/painless/using-datetime-in-painless.md) operation errors in your Painless script. + +## Runtime mappings context + +### Dynamic method not found error + +When working with date fields in runtime mappings, accessing methods directly on the document field object can cause errors if the proper value accessor is not used. + +### Error + +```json +{ + "error": { + "root_cause": [ + { + "type": "script_exception", + "reason": "runtime error", + "script_stack": [ + """emit(orderDate.toInstant().toEpochMilli() + 14400000); + """, + " ^---- HERE" + ], + "script": " ...", + "lang": "painless", + "position": { + "offset": 75, + "start": 61, + "end": 124 + } + } + ], + "type": "search_phase_execution_exception", + "reason": "all shards failed", + "phase": "query", + "grouped": true, + "failed_shards": [ + { + "shard": 0, + "index": "kibana_sample_data_ecommerce", + "node": "CxMTEjvKSEC0k0aTr4OM3A", + "reason": { + "type": "script_exception", + "reason": "runtime error", + "script_stack": [ + """emit(orderDate.toInstant().toEpochMilli() + 14400000); + """, + " ^---- HERE" + ], + "script": " ...", + "lang": "painless", + "position": { + "offset": 75, + "start": 61, + "end": 124 + }, + "caused_by": { + "type": "illegal_argument_exception", + "reason": "dynamic method [org.elasticsearch.index.fielddata.ScriptDocValues.Dates, toInstant/0] not found" + } + } + } + ] + }, + "status": 400 +} +``` + +### Problematic code + +```json +"script": { + "lang": "painless", + "source": """ + def orderDate = doc['order_date']; + emit(orderDate.toInstant().toEpochMilli() + 14400000); + """ +} +``` + +### Root cause + +The script attempts to call `toInstant()` directly on a `ScriptDocValues.Dates` object. Date fields in Painless require accessing the `.value` property to get the actual date value before calling date methods. + +### Solution + +Access the date value using `.value` before calling date methods: + +```json +"script": { + "lang": "painless", + "source": """ + def orderDate = doc['order_date'].value; // added .value here + emit(orderDate.toInstant().toEpochMilli() + 14400000); + """ +} +``` + +### Notes + +* Always use `.value` when accessing single values from document fields in Painless. +* Check for empty fields when the field might not exist in all documents. +* Date arithmetic should be performed on the actual date value, not the field container object. diff --git a/troubleshoot/elasticsearch/painless-field-not-found.md b/troubleshoot/elasticsearch/painless-field-not-found.md new file mode 100644 index 0000000000..287b37a65c --- /dev/null +++ b/troubleshoot/elasticsearch/painless-field-not-found.md @@ -0,0 +1,244 @@ +--- +navigation_title: Field not found (mapping conflicts) +--- + +# Troubleshoot field not found (mapping conflicts) in Painless + +Follow these guidelines to avoid field access errors in your Painless script. + +## A document doesn't have a value for a field + +When working with document fields, attempting to access fields that don't exist in all documents or aren't properly mapped leads to field not found exceptions, causing script failures. + +### Sample error + +```json +{ + "error": { + "root_cause": [ + { + "type": "script_exception", + "reason": "runtime error", + "script_stack": [ + "org.elasticsearch.server@9.0.0/org.elasticsearch.index.fielddata.ScriptDocValues.throwIfEmpty(ScriptDocValues.java:93)", + "org.elasticsearch.server@9.0.0/org.elasticsearch.index.fielddata.ScriptDocValues$Longs.get(ScriptDocValues.java:117)", + "org.elasticsearch.server@9.0.0/org.elasticsearch.index.fielddata.ScriptDocValues$Longs.getValue(ScriptDocValues.java:112)", + "doc['author_score'].value > 50 ? doc['author_score'].value : 1", + " ^---- HERE" + ], + "script": "doc['author_score'].value > 50 ? doc['author_score'].value : 1", + "lang": "painless", + "position": { + "offset": 19, + "start": 0, + "end": 62 + } + } + ], + "type": "search_phase_execution_exception", + "reason": "all shards failed", + "phase": "query", + "grouped": true, + "failed_shards": [ + { + "shard": 0, + "index": "articles", + "node": "hupWdkj_RtmThGjNUiIt_w", + "reason": { + "type": "script_exception", + "reason": "runtime error", + "script_stack": [ + "org.elasticsearch.server@9.0.0/org.elasticsearch.index.fielddata.ScriptDocValues.throwIfEmpty(ScriptDocValues.java:93)", + "org.elasticsearch.server@9.0.0/org.elasticsearch.index.fielddata.ScriptDocValues$Longs.get(ScriptDocValues.java:117)", + "org.elasticsearch.server@9.0.0/org.elasticsearch.index.fielddata.ScriptDocValues$Longs.getValue(ScriptDocValues.java:112)", + "doc['author_score'].value > 50 ? doc['author_score'].value : 1", + " ^---- HERE" + ], + "script": "doc['author_score'].value > 50 ? doc['author_score'].value : 1", + "lang": "painless", + "position": { + "offset": 19, + "start": 0, + "end": 62 + }, + "caused_by": { + "type": "illegal_state_exception", + "reason": "A document doesn't have a value for a field! Use doc[].size()==0 to check if a document is missing a field!" + } + } + } + ] + }, + "status": 400 +} +``` + +### Problematic code + +```json +{ + "query": { + "function_score": { + "query": { + "match_all": {} + }, + "script_score": { + "script": { + "source": "doc['author_score'].value > 50 ? doc['author_score'].value : 1", + "lang": "painless" + } + } + } + } +} +``` + +### Root cause + +A field not found exception occurs when a script tries to access a field that is not defined in the index mappings. If the field is defined in the mappings but has no value in some documents, the script will not fail as long as you first check whether the field has values. + +For example, calling `doc['author_score'].value` directly on a document without that field will cause an error. The recommended approach is to use `doc[].size()==0` to check if the field is missing in a document before accessing its value. + +### Sample documents + +```json +POST articles/_doc +{ + "title": "Complete Guide to Elasticsearch", + "content": "This is a comprehensive guide...", + "author": "John Doe", + "author_score": 85 +} + +POST articles/_doc +{ + "title": "Basic Query Tutorial", + "content": "Learn the fundamentals...", + "author": "Jane Smith" +} +``` + +### Solution 1: Check field existence before accessing + +Always verify field existence using `size()` before accessing field values: + +```json +GET articles/_search +{ + "query": { + "function_score": { + "query": { + "match_all": {} + }, + "script_score": { + "script": { + "source": """ + if (doc['author_score'].size() > 0) { + return doc['author_score'].value > 50 ? doc['author_score'].value : 1; + } else { + return 1; + } + """, + "lang": "painless" + } + } + } + } +} +``` + +### Solution 2: New field API approach + +The [field API](/explore-analyze/scripting/script-fields-api.md) provides a more elegant solution that handles missing values automatically by allowing you to specify default values. This approach is more concise and eliminates the need for explicit field existence checks: + +```json +GET articles/_search +{ + "query": { + "function_score": { + "query": { + "match_all": {} + }, + "script_score": { + "script": { + "source": """ + long authorScore = field('author_score').get(1L); + return authorScore > 50 ? authorScore : 1; + """, + "lang": "painless" + } + } + } + } +} +``` + +### Solution 3: Use the $ shortcut in field API syntax + +With the field API you can make the solution even more concise using the `$` shortcut: + +```json +GET articles/_search +{ + "query": { + "function_score": { + "query": { + "match_all": {} + }, + "script_score": { + "script": { + "source": """ + long authorScore = $('author_score', 1L); + return authorScore > 50 ? authorScore : 1; + """, + "lang": "painless" + } + } + } + } +} +``` + +### Results + +```json +{ + ..., + "hits": { + ..., + "hits": [ + { + "_index": "articles", + "_id": "pnZXL5kBTbKqUnB52aCH", + "_score": 85, + "_source": { + "title": "Complete Guide to Elasticsearch", + "content": "This is a comprehensive guide...", + "author": "John Doe", + "author_score": 85 + } + }, + { + "_index": "articles", + "_id": "i6hXL5kB0eMypkDY3mQ4", + "_score": 1, + "_source": { + "title": "Basic Query Tutorial", + "content": "Learn the fundamentals...", + "author": "Jane Smith" + } + } + ] + } +} +``` + +### Notes + +* **Field presence:** Always check if fields exist before accessing them using `.size() > 0`. +* **Document variation:** Not all documents are guaranteed to have the same field structure. +* **Mapping awareness:** A field must be defined in the index mappings to be accessed with doc values, and its value in each document must be validated. +* **Field API:** The `field` API and `$` shortcut handle missing values gracefully with default values. +* **Compatibility:** Some field types (like `text` or `geo`) [aren't yet supported](/explore-analyze/scripting/script-fields-api.md#_supported_mapped_field_types) by the field API; continue using `doc` for those. + + diff --git a/troubleshoot/elasticsearch/painless-ingest-pipeline-failures.md b/troubleshoot/elasticsearch/painless-ingest-pipeline-failures.md new file mode 100644 index 0000000000..f0d9e2effc --- /dev/null +++ b/troubleshoot/elasticsearch/painless-ingest-pipeline-failures.md @@ -0,0 +1,137 @@ +--- +navigation_title: Ingest pipeline failures +--- + +# Troubleshoot ingest pipeline failures in Painless + +Follow these guidelines to avoid [ingest pipeline](elasticsearch://reference/scripting-languages/painless/painless-ingest-processor-context.md) script errors in your Painless script. + +## Date conversion + +### Class cast exception when converting date data types + +When converting time strings to nanoseconds in ingest pipelines, attempting to perform arithmetic operations directly on string values without proper date parsing leads to type casting errors. + +### Sample error + +```json +{ + "docs": [ + { + "error": { + "root_cause": [ + { + "type": "script_exception", + "reason": "runtime error", + "script_stack": [ + "ctx.nanoseconds = ctx.time_field * 1000000;", + " ^---- HERE" + ], + "script": " ...", + "lang": "painless", + "position": { + "offset": 32, + "start": 11, + "end": 63 + } + } + ], + "type": "script_exception", + "reason": "runtime error", + "script_stack": [ + "ctx.nanoseconds = ctx.time_field * 1000000;", + " ^---- HERE" + ], + "script": " ...", + "lang": "painless", + "position": { + "offset": 32, + "start": 11, + "end": 63 + }, + "caused_by": { + "type": "class_cast_exception", + "reason": "Cannot apply [*] operation to types [java.lang.String] and [java.lang.Integer]." + } + } + } + ] +} +``` + +### Problematic code + +```json +{ + "script": { + "source": """ + ctx.nanoseconds = ctx.time_field * 1000000; + """ + } +} +``` + +### Root cause + +When accessing fields via `ctx.time_field` in ingest pipelines, the values are not automatically parsed to their mapped field types. The script attempts to multiply a string value (time field) directly with an integer. Time strings like `"00:00:00.022"` remain as strings and need to be properly parsed as dates and converted to epoch milliseconds before performing arithmetic operations. + +### Solution: Use `SimpleDateFormat` in the script processor + +Parse the time string directly using SimpleDateFormat and get epoch milliseconds: + +```json +POST _ingest/pipeline/_simulate +{ + "pipeline": { + "description": "Parse time and convert to nanoseconds", + "processors": [ + { + "script": { + "source": """ + SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS"); + long millis = sdf.parse(ctx.time_field).getTime(); + ctx.timestamp_nanos = millis * 1000000L; + """ + } + } + ] + }, + "docs": [ + { + "_index": "index", + "_id": "id", + "_source": { + "time_field": "00:00:00.022" + } + } + ] +} +``` + +### Result + +```json +{ + "docs": [ + { + "doc": { + "_index": "index", + "_version": "-3", + "_id": "id", + "_source": { + "time_field": "00:00:00.022", + "timestamp_nanos": 22000000 + }, + "_ingest": { + "timestamp": "2025-09-02T17:40:42.175772728Z" + } + } + } + ] +} +``` + +### Note + +* Time strings like `"HH:mm:ss.SSS"` must be explicitly parsed before arithmetic operations. +* Using `SimpleDateFormat` in a script processor allows custom parsing. diff --git a/troubleshoot/elasticsearch/painless-null-pointer-exceptions.md b/troubleshoot/elasticsearch/painless-null-pointer-exceptions.md new file mode 100644 index 0000000000..8d78cdfec1 --- /dev/null +++ b/troubleshoot/elasticsearch/painless-null-pointer-exceptions.md @@ -0,0 +1,166 @@ +--- +navigation_title: Null pointer exceptions +--- + +# Troubleshoot null pointer exceptions in Painless + +Follow these guidelines to avoid null pointer exceptions in your Painless script. + +## Null\_pointer\_exception + +Null pointer exceptions in Painless scripts often occur due to using field access patterns that are not valid for the current script context. + +### Wrong field access patterns in script contexts + +When writing Painless scripts in different [contexts](elasticsearch://reference/scripting-languages/painless/painless-contexts.md), using wrong field access patterns leads to null pointer exceptions because field access methods vary depending on the script execution context. + +### Sample error + +```json +{ + "error": { + "root_cause": [ + { + "type": "script_exception", + "reason": "runtime error", + "script_stack": [ + "params['_source'].tags.size() > 2", + " ^---- HERE" + ], + "script": "params['_source'].tags.size() > 2", + "lang": "painless", + "position": { + "offset": 17, + "start": 0, + "end": 33 + } + } + ], + "type": "search_phase_execution_exception", + "reason": "all shards failed", + "phase": "query", + "grouped": true, + "failed_shards": [ + { + "shard": 0, + "index": "products", + "node": "hupWdkj_RtmThGjNUiIt_w", + "reason": { + "type": "script_exception", + "reason": "runtime error", + "script_stack": [ + "params['_source'].tags.size() > 2", + " ^---- HERE" + ], + "script": "params['_source'].tags.size() > 2", + "lang": "painless", + "position": { + "offset": 17, + "start": 0, + "end": 33 + }, + "caused_by": { + "type": "null_pointer_exception", + "reason": "cannot access method/field [tags] from a null def reference" + } + } + } + ] + }, + "status": 400 +}á +``` + +### Problematic code + +```json +{ + "query": { + "bool": { + "filter": { + "script": { + "script": { + "source": "params['_source'].tags.size() > 2", + "lang": "painless" + } + } + } + } + } +} +``` + +### Sample data + +```json +POST products/_doc +{ + "name": "Laptop", + "price": 999.99, + "category": "electronics", + "tags": ["premium", "gaming", "portable"] +} +``` + +### Root cause + +A common cause of null pointer exceptions in Painless scripts is attempting to access document fields using incorrect access patterns for the specific [script context](elasticsearch://reference/scripting-languages/painless/painless-contexts.md). In Painless, field access methods are context-dependent. For more information, refer to "Painless syntax-context bridge" in the Explore and Analyze documentation. + +The error occurs because `params['_source']` is not available in script filter contexts. In script filters, field values must be accessed through `doc` values, not through the `params['_source']` map. + +### Solution: Use correct field access pattern for context + +For script filter contexts, use `doc` values instead of `params._source`: + +```json +GET products/_search +{ + "query": { + "bool": { + "filter": { + "script": { + "script": { + "source": "doc['tags.keyword'].size() > 2", + "lang": "painless" + } + } + } + } + } +} +``` + +### Results + +```json +{ + ..., + "hits": { + ..., + "hits": [ + { + ..., + "_source": { + "name": "Laptop", + "price": 999.99, + "category": "electronics", + "tags": [ + "premium", + "gaming", + "portable" + ] + } + } + ] + } +} +``` + +### Notes + +* **Context matters:** Always verify the correct field access pattern for your script context. +* **Context limitations:** Script filters cannot access `params['_source']` . +* **Field mapping:** Use `.keyword` suffix for text fields when accessing via doc values. + +For more details related to Painless context, refer to [Painless context documentation](elasticsearch://reference/scripting-languages/painless/painless-contexts.md) and Painless syntax-context bridge. + diff --git a/troubleshoot/elasticsearch/painless-regex-pattern-matching-failures.md b/troubleshoot/elasticsearch/painless-regex-pattern-matching-failures.md new file mode 100644 index 0000000000..c96a4d5e84 --- /dev/null +++ b/troubleshoot/elasticsearch/painless-regex-pattern-matching-failures.md @@ -0,0 +1,120 @@ +--- +navigation_title: Regex pattern matching failures +--- + +# Troubleshoot regex pattern matching failures in Painless + +Follow these guidelines to avoid [regex](elasticsearch://reference/scripting-languages/painless/painless-regexes) operation errors in your Painless script. + +## Regex compilation and usage errors in Painless scripts + +Regex operations in Painless can fail for several reasons: the regex feature is disabled, there is incorrect matcher usage, or there are malformed regex patterns. These errors are common when developers assume that standard Java regex behavior applies directly to Painless. + +### Sample error + +```json +{ + "error": { + "root_cause": [ + { + "type": "script_exception", + "reason": "runtime error", + "script_stack": [ + "java.base/java.util.regex.Matcher.checkMatch(Matcher.java:1850)", + "java.base/java.util.regex.Matcher.group(Matcher.java:685)", + """return /(?<=SHIPPER:).*?(?=\\n)/.matcher(orderLog).group(0); + """, + " ^---- HERE" + ], + "script": " ...", + "lang": "painless", + "position": { + "offset": 176, + "start": 126, + "end": 191 + } + } + ], + "type": "script_exception", + "reason": "runtime error", + "script_stack": [ + "java.base/java.util.regex.Matcher.checkMatch(Matcher.java:1850)", + "java.base/java.util.regex.Matcher.group(Matcher.java:685)", + """return /(?<=SHIPPER:).*?(?=\\n)/.matcher(orderLog).group(0); + """, + " ^---- HERE" + ], + "script": " ...", + "lang": "painless", + "position": { + "offset": 176, + "start": 126, + "end": 191 + }, + "caused_by": { + "type": "illegal_state_exception", + "reason": "No match found" + } + }, + "status": 400 +} +``` + +### Problematic code + +```json +{ + "script": { + "lang": "painless", + "source": """ + String orderLog = "Order processing initiated\\nSHIPPER: SHIP-EX EXPRESS DELIVERY\\nTracking number generated"; + + return /(?<=SHIPPER:).*?(?=\\n)/.matcher(orderLog).group(0); + """ + } +} +``` + +### Root cause + +The error occurs because the `group()` method is called on a Matcher before calling `find()`. You must explicitly search for matches before accessing groups. This is a common mistake when developers expect the matcher to automatically find matches. + +### Solution: Call find() before accessing groups + +Always call `find()` before using `group()` methods: + +```json +POST _scripts/painless/_execute +{ + "script": { + "lang": "painless", + "source": """ + String orderLog = "Order processing initiated\\nSHIPPER: SHIP-EX EXPRESS DELIVERY\\nTracking number generated"; + + Matcher m = /(?<=SHIPPER:).*?(?=\\n)/.matcher(orderLog); + boolean found = m.find(); + + return found ? m.group(0).trim() : "No match"; + """ + } +} +``` + +### Results + +```json +{ + "result": "SHIP-EX EXPRESS DELIVERY" +} +``` + +### Notes + +* **Call find() first:** Always use `matcher.find()` before accessing groups. +* **Enable regex:** Set `script.painless.regex.enabled=true` in the `elasticsearch.yml` settings file if regex is disabled. +* **Group numbering:** Use `group(0)` for the entire match, `group(1)` for first capture group, etc. +* **Performance impact:** Regex operations can be expensive, especially with complex patterns. + + + + diff --git a/troubleshoot/elasticsearch/painless-runtime-field-exceptions.md b/troubleshoot/elasticsearch/painless-runtime-field-exceptions.md new file mode 100644 index 0000000000..9809489a63 --- /dev/null +++ b/troubleshoot/elasticsearch/painless-runtime-field-exceptions.md @@ -0,0 +1,161 @@ +--- +navigation_title: Runtime field exceptions +--- + +# Troubleshoot runtime field exceptions in Painless + +Follow these guidelines to avoid [runtime field](elasticsearch://reference/scripting-languages/painless/painless-runtime-fields-context.md) exceptions in your Painless script. + +## Runtime mappings + +### Using return instead of emit in runtime field + +When creating runtime mappings, using `return` instead of `emit` to output values leads to compilation errors, as runtime field scripts require the `emit()` function to produce field values. + +### Sample error + +```json +{ + "error": { + "root_cause": [ + { + "type": "class_cast_exception", + "reason": "class_cast_exception: Cannot cast from [java.lang.String] to [void]." + } + ], + "type": "search_phase_execution_exception", + "reason": "all shards failed", + "phase": "query", + "grouped": true, + "failed_shards": [ + { + "shard": 0, + "index": "users", + "node": "hupWdkj_RtmThGjNUiIt_w", + "reason": { + "type": "script_exception", + "reason": "compile error", + "script_stack": [ + """... Doe"; + + return firstName + " " + lastNam ...""", + " ^---- HERE" + ], + "script": """ + String firstName = "John"; + String lastName = "Doe"; + + return firstName + " " + lastName; + """, + "lang": "painless", + "position": { + "offset": 92, + "start": 67, + "end": 117 + }, + "caused_by": { + "type": "class_cast_exception", + "reason": "class_cast_exception: Cannot cast from [java.lang.String] to [void]." + } + } + } + ], + "caused_by": { + "type": "class_cast_exception", + "reason": "class_cast_exception: Cannot cast from [java.lang.String] to [void]." + } + }, + "status": 400 +} +``` + +### Problematic code + +```json +{ + "runtime_mappings": { + "full_name": { + "type": "keyword", + "script": { + "source": """ + String firstName = "John"; + String lastName = "Doe"; + + return firstName + " " + lastName; + """ + } + } + } +} +``` + +### Root cause + +Runtime field scripts use `emit()` to produce values, not `return`. The `emit()` function is specifically designed for runtime mappings to output field values, while `return` is used in other Painless contexts like script queries or update scripts. The error occurs because runtime field scripts expect void return type, but the script attempts to return a String value. + +### Solution: Replace return with emit + +Replace `return` statements with `emit()` calls: + +```json +POST users/_search +{ + "fields": [ + { + "field": "*", + "include_unmapped": "true" + } + ], + "runtime_mappings": { + "full_name": { + "type": "keyword", + "script": { + "source": """ + String firstName = "John"; + String lastName = "Doe"; + + emit(firstName + " " + lastName); + """ + } + } + } +} +``` + +### Results + +```json +{ + ..., + "hits": { + ..., + "hits": [ + { + ..., + "_source": { + "user": { + "name": "Jane Doe" + } + }, + "fields": { + "user.name.keyword": [ + "Jane Doe" + ], + "user_info": [ + "incomplete: Jane Doe" + ], + "user.name": [ + "Jane Doe" + ] + } + } + ] + } +} +``` + +### Notes + +* Runtime field scripts must use `emit()` to output values, not `return`. +* `emit()` can be called multiple times in a script to emit multiple values. + diff --git a/troubleshoot/elasticsearch/painless-sandbox-limitations.md b/troubleshoot/elasticsearch/painless-sandbox-limitations.md new file mode 100644 index 0000000000..c67d955e66 --- /dev/null +++ b/troubleshoot/elasticsearch/painless-sandbox-limitations.md @@ -0,0 +1,139 @@ +--- +navigation_title: Sandbox limitations +--- + +# Troubleshoot sandbox limitations in Painless + +Follow these guidelines to avoid Painless sandbox restriction errors in your script. + +## Painless sandbox restrictions causing compilation errors + +Painless implements sandbox limitations that differ from standard Java syntax and behavior. These restrictions are designed to optimize performance and prevent logical errors, which can lead to unexpected compilation errors when developers use common Java patterns. One limitation is that empty foreach loops are not allowed. + +### Sample error + +```json +{ + "error": { + "root_cause": [ + { + "type": "script_exception", + "reason": "compile error", + "script_stack": [ + """... keyboard": 85]; + + for (item in products.ent ...""", + " ^---- HERE" + ], + "script": """ + Map products = ["laptop": 1200, "mouse": 25, "keyboard": 85]; + + for (item in products.entrySet()) + { + + + } + + return false; + """, + "lang": "painless", + "position": { + "offset": 80, + "start": 55, + "end": 105 + } + } + ], + "type": "script_exception", + "reason": "compile error", + "script_stack": [ + """... keyboard": 85]; + + for (item in products.ent ...""", + " ^---- HERE" + ], + "script": """ + Map products = ["laptop": 1200, "mouse": 25, "keyboard": 85]; + + for (item in products.entrySet()) + { + + + } + + return false; + """, + "lang": "painless", + "position": { + "offset": 80, + "start": 55, + "end": 105 + }, + "caused_by": { + "type": "illegal_argument_exception", + "reason": "extraneous foreach loop" + } + }, + "status": 400 +} +``` + +### Problematic code + +```json +{ + "script": { + "lang": "painless", + "source": """ + Map products = ["laptop": 1200, "mouse": 25, "keyboard": 85]; + + for (item in products.entrySet()) + { + + + } + + return false; + """ + } +} +``` + +### Root cause + +* **Empty loop blocks:** Painless does not allow empty foreach loops as an intentional feature to enhance usability and performance. +* **Performance optimization:** Since scripts run once per document and there may be millions of documents, empty loops are considered wasteful. + + +The error occurs because Painless expects meaningful code inside loop blocks and treats empty loops as potential bugs or risks. + +### Solution: Add code inside loop blocks + +Always include actual code inside foreach loops. For example: + +```json +POST _scripts/painless/_execute +{ + "script": { + "lang": "painless", + "source": """ + Map products = ["laptop": 1200, "mouse": 25, "keyboard": 85]; + String inventory = ""; + + for (item in products.entrySet()) + { + inventory += item.getKey() + " costs $" + item.getValue() + ". "; + } + + return inventory; + """ + } +} +``` + +### Notes + +* **Empty loops:** Painless intentionally prohibits empty foreach loops for performance reasons. +* **Syntax differences:** Painless syntax differs from Java in several ways to optimize execution and prevent logical errors. + + diff --git a/troubleshoot/elasticsearch/painless-script-score-calculation-errors.md b/troubleshoot/elasticsearch/painless-script-score-calculation-errors.md new file mode 100644 index 0000000000..d5d716f6d0 --- /dev/null +++ b/troubleshoot/elasticsearch/painless-script-score-calculation-errors.md @@ -0,0 +1,185 @@ +--- +navigation_title: Script score calculation errors +--- + +# Troubleshoot script score calculation errors in Painless + +Follow these guidelines to avoid scoring calculation errors in your Painless script. + +## script\_score script returned an invalid score + +When using [`script_score`](elasticsearch://reference/query-languages/query-dsl/query-dsl-script-score-query.md) with type `double`, + it can return unexpected null values, negative values `0.0` or Infinity, causing documents to receive a score of `0` or be excluded from results entirely. This commonly occurs when field access patterns don't account for missing values or when mathematical operations result in null propagation. + +### Sample error + +```json +{ + "error": { + "root_cause": [ + { + "type": "illegal_argument_exception", + "reason": "script_score script returned an invalid score [-Infinity] for doc [0]. Must be a non-negative score!" + } + ], + "type": "search_phase_execution_exception", + "reason": "all shards failed", + "phase": "query", + "grouped": true, + "failed_shards": [ + { + "shard": 0, + "index": "products", + "node": "CxMTEjvKSEC0k0aTr4OM3A", + "reason": { + "type": "illegal_argument_exception", + "reason": "script_score script returned an invalid score [-Infinity] for doc [0]. Must be a non-negative score!" + } + } + ], + "caused_by": { + "type": "illegal_argument_exception", + "reason": "script_score script returned an invalid score [-Infinity] for doc [0]. Must be a non-negative score!", + "caused_by": { + "type": "illegal_argument_exception", + "reason": "script_score script returned an invalid score [-Infinity] for doc [0]. Must be a non-negative score!" + } + } + }, + "status": 400 +} +``` + +### Problematic code + +```json +{ + "query": { + "script_score": { + "query": { + "match_all": {} + }, + "script": { + "lang": "painless", + "source": """ + double price = 0.0; // Simulating problematic calculation + double rating = 5.0; + + return Math.log(price) * rating; + """ + } + } + } +} +``` + +### Root cause + +The error occurs because of mathematical edge cases in calculations: + +1. **Math.log() with zero or negative values:** `Math.log(0)` returns negative infinity, `Math.log(-x)` returns `NaN`. +2. **Division by zero:** Operations like `x/0` throw an arithmetic\_exception. +3. **NaN propagation:** Any mathematical operation involving `NaN` results in `NaN`. +4. **Infinity calculations:** Operations with infinity often result in `NaN` or unexpected values. + +When a script returns `NaN`, negative infinity, or other invalid numbers, Painless converts the score to 0.0, causing unexpected ranking behavior. + +### Solution: Add mathematical safety checks + +Always validate mathematical inputs and handle edge cases: + +```json +GET products/_search +{ + "query": { + "script_score": { + "query": { + "match_all": {} + }, + "script": { + "lang": "painless", + "source": """ + double price = 0.0; + double rating = 5.0; + + double safePrice = Math.max(price, 1.0); // Ensure > 0 for log + + // Calculate score with safety checks + double logPrice = Math.log(safePrice); + double score = logPrice * rating; + + // Handle NaN or infinity results + if (Double.isNaN(score) || Double.isInfinite(score)) { + return 1.0; + } + + return Math.max(score, 0.1); // Ensure minimum positive score + """ + } + } + } +} +``` + +### Sample documents + +```json +POST products/_doc +{ + "name": "Premium Laptop", + "price": 999.99, + "rating": 4.7, + "category": "electronics" +} + +POST products/_doc +{ + "name": "Free Software", + "price": 0, + "rating": 5.0, + "category": "software" +} +``` + +### Results + +```json +{ + ..., + "hits": { + ..., + "hits": [ + { + "_index": "products", + "_id": "j6gZNZkB0eMypkDYmmSC", + "_score": 0.1, + "_source": { + "name": "Premium Laptop", + "price": 999.99, + "rating": 4.7, + "category": "electronics" + } + }, + { + "_index": "products", + "_id": "kKgZNZkB0eMypkDYn2SP", + "_score": 0.1, + "_source": { + "name": "Free Software", + "price": 0, + "rating": 5, + "category": "software" + } + } + ] + } +} +``` + +### Notes + +* **Mathematical safety:** Validate inputs for functions like `Math.log()`. +* **Default values:** Provide meaningful defaults for missing fields to maintain consistent scoring. +* **Minimum scores:** Ensure scripts return positive values to avoid zero scores. +* **Null handling:** Mathematical operations with null values propagate null throughout the calculation. + diff --git a/troubleshoot/elasticsearch/painless-scripting.md b/troubleshoot/elasticsearch/painless-scripting.md new file mode 100644 index 0000000000..eea39dd251 --- /dev/null +++ b/troubleshoot/elasticsearch/painless-scripting.md @@ -0,0 +1,23 @@ +--- +navigation_title: Painless scripting +--- + +# Troubleshoot Painless scripting in {{es}} + +Use the topics in this section to troubleshoot common errors in your [Painless scripts](/explore-analyze/scripting/modules-scripting-painless.md). + +* [Array/list manipulation errors](/troubleshoot/elasticsearch/painless-array-list-manipulation-errors.md) +* [Date math errors](/troubleshoot/elasticsearch/painless-date-math-errors.md) +* [Field not found (mapping conflicts)](/troubleshoot/elasticsearch/painless-field-not-found.md) +* [Ingest pipeline failures](/troubleshoot/elasticsearch/painless-ingest-pipeline-failures.md) +* [Null pointer exceptions](/troubleshoot/elasticsearch/painless-null-pointer-exceptions.md) +* [Regex pattern matching failures](/troubleshoot/elasticsearch/painless-regex-pattern-matching-failures.md) +* [Runtime field exceptions](/troubleshoot/elasticsearch/painless-runtime-field-exceptions.md) +* [Sandbox limitations](/troubleshoot/elasticsearch/painless-sandbox-limitations.md) +* [Script score calculation errors](/troubleshoot/elasticsearch/painless-script-score-calculation-errors.md) +* [Subfield access](/troubleshoot/elasticsearch/painless-subfield-access.md) +* [Type casting issues](/troubleshoot/elasticsearch/painless-type-casting-issues.md) + +## Additional resources +* [Troubleshooting overview](/troubleshoot/index.md) +* [Contact us](/troubleshoot/index.md#contact-us) \ No newline at end of file diff --git a/troubleshoot/elasticsearch/painless-subfield-access.md b/troubleshoot/elasticsearch/painless-subfield-access.md new file mode 100644 index 0000000000..f39c019321 --- /dev/null +++ b/troubleshoot/elasticsearch/painless-subfield-access.md @@ -0,0 +1,283 @@ +--- +navigation_title: Subfield access +--- + +# Troubleshoot subfield access in Painless + +Follow these guidelines to avoid nested field access errors in your Painless script. + +## No field found for \[field\] in mapping + +When accessing subfields through doc accessor, using incorrect syntax or trying to access non-existent fields without proper validation leads to runtime errors. + +### Sample error + +```json +{ + "error": { + "root_cause": [ + { + "type": "script_exception", + "reason": "runtime error", + "script_stack": [ + "org.elasticsearch.server@9.0.0/org.elasticsearch.search.lookup.LeafDocLookup.getFactoryForDoc(LeafDocLookup.java:146)", + "org.elasticsearch.server@9.0.0/org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:186)", + "org.elasticsearch.server@9.0.0/org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:33)", + """start = doc['event'].start.value; + def """, + " ^---- HERE" + ], + "script": " ...", + "lang": "painless", + "position": { + "offset": 95, + "start": 83, + "end": 131 + } + } + ], + "type": "search_phase_execution_exception", + "reason": "all shards failed", + "phase": "query", + "grouped": true, + "failed_shards": [ + { + "shard": 0, + "index": "events", + "node": "CxMTEjvKSEC0k0aTr4OM3A", + "reason": { + "type": "script_exception", + "reason": "runtime error", + "script_stack": [ + "org.elasticsearch.server@9.0.0/org.elasticsearch.search.lookup.LeafDocLookup.getFactoryForDoc(LeafDocLookup.java:146)", + "org.elasticsearch.server@9.0.0/org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:186)", + "org.elasticsearch.server@9.0.0/org.elasticsearch.search.lookup.LeafDocLookup.get(LeafDocLookup.java:33)", + """start = doc['event'].start.value; + def """, + " ^---- HERE" + ], + "script": " ...", + "lang": "painless", + "position": { + "offset": 95, + "start": 83, + "end": 131 + }, + "caused_by": { + "type": "illegal_argument_exception", + "reason": "No field found for [event] in mapping" + } + } + } + ] + }, + "status": 400 +} +``` + +### Problematic approaches + +Following are some common incorrect ways to access subfields: + +```json +{ + "runtime_mappings": { + "event_duration_match": { + "type": "boolean", + "script": { + "source": """ + // Incorrect approach 1: trying to access nested property + def start = doc['event'].start.value; + def end = doc['event'].end.value; + emit(start == end); + """ + } + } + } +} +``` + +Or: + +```json +{ + "runtime_mappings": { + "event_duration_match": { + "type": "boolean", + "script": { + "source": """ + // Incorrect approach 2: using bracket notation incorrectly + def start = doc['event']['start'].value; + def end = doc['event']['end'].value; + emit(start == end); + """ + } + } + } +} +``` + +### Sample data + +```json +PUT events/_doc/1 +{ + "title": "Conference Call", + "event": { + "start": "2024-01-15T09:00:00Z", + "end": "2024-01-15T10:00:00Z" + } +} + +PUT events/_doc/2 +{ + "title": "Team Meeting", + "event": { + "start": "2024-01-15T14:00:00Z", + "end": "2024-01-15T14:00:00Z" + } +} + +PUT events/_doc/3 +{ + "title": "Quick Update" +} +``` + +### Root cause + +When accessing subfields in Painless scripts using the `doc` accessor, the correct syntax requires using the full dot notation path as a single string (`doc['parent.child’]`), not as a separate property access or bracket notation. This applies to all Painless contexts where `doc` accessor is available, including runtime mapping, script queries, aggregations, and ingest processors. + +The error occurs because `doc[‘event’]` attempts to find a field named “event” rather than accessing subfields within the event object. + +### Solution: Correct subfield access with validation + +Use full dot notation and validate that the field exists:: + +```json +POST events/_search +{ + "fields": [ + { + "field": "*", + "include_unmapped": "true" + } + ], + "runtime_mappings": { + "event_duration_match": { + "type": "boolean", + "script": { + "source": """ + if (doc.containsKey('event.start') && doc.containsKey('event.end') && doc['event.start'].size() > 0 && doc['event.end'].size() > 0) { + + def start = doc['event.start'].value; + def end = doc['event.end'].value; + emit(start == end); + } else { + emit(false); + } + """ + } + } + } +} +``` + +### Results + +```json +{ + ..., + "hits": { + ..., + "hits": [ + { + ..., + "_source": { + "title": "Conference Call", + "event": { + "start": "2024-01-15T09:00:00Z", + "end": "2024-01-15T10:00:00Z" + } + }, + "fields": { + "title.keyword": [ + "Conference Call" + ], + "event_duration_match": [ + false + ], + "title": [ + "Conference Call" + ], + "event": [ + { + "start": [ + "2024-01-15T09:00:00.000Z" + ], + "end": [ + "2024-01-15T10:00:00.000Z" + ] + } + ] + } + }, + { + ..., + "_source": { + "title": "Team Meeting", + "event": { + "start": "2024-01-15T14:00:00Z", + "end": "2024-01-15T14:00:00Z" + } + }, + "fields": { + "title.keyword": [ + "Team Meeting" + ], + "event_duration_match": [ + false + ], + "title": [ + "Team Meeting" + ], + "event": [ + { + "start": [ + "2024-01-15T14:00:00.000Z" + ], + "end": [ + "2024-01-15T14:00:00.000Z" + ] + } + ] + } + }, + { + ..., + "_source": { + "title": "Quick Update" + }, + "fields": { + "title.keyword": [ + "Quick Update" + ], + "title": [ + "Quick Update" + ], + "event_duration_match": [ + false + ] + } + } + ] + } +} +``` + +### Notes + +* Use full dot notation as a single string: `doc['parent.child’]` not `doc['parent.['child’].` +* Always validate field existence using `.size() > 0` before accessing subfield values. +* Field validation is crucial when documents have varying object structures. + diff --git a/troubleshoot/elasticsearch/painless-type-casting-issues.md b/troubleshoot/elasticsearch/painless-type-casting-issues.md new file mode 100644 index 0000000000..1a41c4a81d --- /dev/null +++ b/troubleshoot/elasticsearch/painless-type-casting-issues.md @@ -0,0 +1,212 @@ +--- +navigation_title: Type casting issues +--- + +# Troubleshoot type casting issues in Painless + +Follow these guidelines to avoid type conversion errors in your Painless script. + +## Cannot cast from \[type\_number\] to \[type\_number\] + +When performing [type casting](elasticsearch://reference/scripting-languages/painless/painless-casting.md) in Painless scripts, attempting implicit conversions or casting incompatible types without proper validation leads to compilation and runtime errors. + +### Sample error + +```json +{ + "error": { + "root_cause": [ + { + "type": "class_cast_exception", + "reason": "class_cast_exception: Cannot cast from [double] to [int]." + } + ], + "type": "search_phase_execution_exception", + "reason": "all shards failed", + "phase": "query", + "grouped": true, + "failed_shards": [ + { + "shard": 0, + "index": "products", + "node": "CxMTEjvKSEC0k0aTr4OM3A", + "reason": { + "type": "script_exception", + "reason": "compile error", + "script_stack": [ + "... int discountedPrice = price * discount; // Err ...", + " ^---- HERE" + ], + "script": """ + double price = doc['price'].value; + double discount = 0.85; + int discountedPrice = price * discount; // Error: implicit cast + emit(discountedPrice); + """, + "lang": "painless", + "position": { + "offset": 112, + "start": 87, + "end": 137 + }, + "caused_by": { + "type": "class_cast_exception", + "reason": "class_cast_exception: Cannot cast from [double] to [int]." + } + } + } + ], + "caused_by": { + "type": "class_cast_exception", + "reason": "class_cast_exception: Cannot cast from [double] to [int]." + } + }, + "status": 400 +} +``` + +### Problematic code + +```json +{ + "runtime_mappings": { + "discounted_price": { + "type": "long", + "script": { + "source": """ + double price = doc['price'].value; + double discount = 0.85; + int discountedPrice = price * discount; // Error: implicit cast + emit(discountedPrice); + """ + } + } + } +} +``` + +### Sample data + +```json +PUT products/_doc/1 +{ + "name": "Laptop", + "price": 999.99 +} + +PUT products/_doc/2 +{ + "name": "Mouse", + "price": 25 +} +``` + +### Root cause + +Painless has [specific rules](https://www.elastic.co/docs/reference/scripting-languages/painless/painless-casting) for implicit and explicit type casting between numeric types. While some numeric conversions are allowed implicitly (widening conversions like `int` into `double`), narrowing conversions like `double` to `int` require explicit casting. The script attempts to assign a `double` result to an `int` variable without explicit casting, which causes a compilation error since this is a narrowing conversion that could lose precision. Additionally, field values may be null or of unexpected types, requiring proper validation before casting. + +### Solution: Use explicit numeric type casting + +Use explicit casting with proper validation: + +```json +POST products/_search +{ + "fields": [ + { + "field": "*", + "include_unmapped": "true" + } + ], + "runtime_mappings": { + "discounted_price": { + "type": "long", + "script": { + "source": """ + if (doc['price'].size() > 0) { + def value = doc['price'].value; + + if (value != null && value instanceof Number) { + double price = (double) value; + double discount = 0.85; + long discountedPrice = (long)(price * discount); + emit(discountedPrice); + } else { + emit(0L); + } + } else { + emit(0L); + } + """ + } + } + } +} +``` + +### Results + +```json +{ + ..., + "hits": { + ..., + "hits": [ + { + "_index": "products", + "_id": "1", + "_score": 1, + "_source": { + "name": "Laptop", + "price": 999.99 + }, + "fields": { + "name": [ + "Laptop" + ], + "name.keyword": [ + "Laptop" + ], + "price": [ + 999.99 + ], + "discounted_price": [ + 849 + ] + } + }, + { + "_index": "products", + "_id": "2", + "_score": 1, + "_source": { + "name": "Mouse", + "price": 25 + }, + "fields": { + "name": [ + "Mouse" + ], + "name.keyword": [ + "Mouse" + ], + "price": [ + 25 + ], + "discounted_price": [ + 21 + ] + } + } + ] + } +} +``` + +### Notes + +* Validate field existence using `.size() > 0` before accessing values. +* Check for null values using `value != null` before casting. +* Use `instanceof Number` to verify the value is numeric before casting. +* Handle missing fields gracefully with default values. +* When working with {{es}} field values, always validate the actual field type before assuming. diff --git a/troubleshoot/toc.yml b/troubleshoot/toc.yml index 7ed894a8bb..c464c1786e 100644 --- a/troubleshoot/toc.yml +++ b/troubleshoot/toc.yml @@ -51,6 +51,19 @@ toc: - file: elasticsearch/diagnosing-unknown-repositories.md - file: elasticsearch/diagnosing-invalid-repositories.md - file: elasticsearch/repeated-snapshot-failures.md + - file: elasticsearch/painless-scripting.md + children: + - file: elasticsearch/painless-array-list-manipulation-errors.md + - file: elasticsearch/painless-date-math-errors.md + - file: elasticsearch/painless-field-not-found.md + - file: elasticsearch/painless-ingest-pipeline-failures.md + - file: elasticsearch/painless-null-pointer-exceptions.md + - file: elasticsearch/painless-regex-pattern-matching-failures.md + - file: elasticsearch/painless-runtime-field-exceptions.md + - file: elasticsearch/painless-sandbox-limitations.md + - file: elasticsearch/painless-script-score-calculation-errors.md + - file: elasticsearch/painless-subfield-access.md + - file: elasticsearch/painless-type-casting-issues.md - file: elasticsearch/troubleshooting-searches.md - file: elasticsearch/start-ilm.md - file: elasticsearch/index-lifecycle-management-errors.md From b18115c821e73c1d4df93d7e5e70ea377572d663 Mon Sep 17 00:00:00 2001 From: David Kilfoyle Date: Fri, 24 Oct 2025 15:03:26 -0400 Subject: [PATCH 2/5] add applies_to --- .../elasticsearch/painless-array-list-manipulation-errors.md | 5 +++++ troubleshoot/elasticsearch/painless-date-math-errors.md | 5 +++++ troubleshoot/elasticsearch/painless-field-not-found.md | 5 +++++ .../elasticsearch/painless-ingest-pipeline-failures.md | 5 +++++ .../elasticsearch/painless-null-pointer-exceptions.md | 5 +++++ .../painless-regex-pattern-matching-failures.md | 5 +++++ .../elasticsearch/painless-runtime-field-exceptions.md | 5 +++++ troubleshoot/elasticsearch/painless-sandbox-limitations.md | 5 +++++ .../painless-script-score-calculation-errors.md | 5 +++++ troubleshoot/elasticsearch/painless-scripting.md | 5 +++++ troubleshoot/elasticsearch/painless-subfield-access.md | 5 +++++ troubleshoot/elasticsearch/painless-type-casting-issues.md | 5 +++++ 12 files changed, 60 insertions(+) diff --git a/troubleshoot/elasticsearch/painless-array-list-manipulation-errors.md b/troubleshoot/elasticsearch/painless-array-list-manipulation-errors.md index a1802c0821..ecde8f7638 100644 --- a/troubleshoot/elasticsearch/painless-array-list-manipulation-errors.md +++ b/troubleshoot/elasticsearch/painless-array-list-manipulation-errors.md @@ -1,5 +1,10 @@ --- navigation_title: Array/list manipulation errors +applies_to: + stack: ga + serverless: ga +products: + - id: elasticsearch --- # Troubleshoot array/list manipulation errors in Painless diff --git a/troubleshoot/elasticsearch/painless-date-math-errors.md b/troubleshoot/elasticsearch/painless-date-math-errors.md index e51b28559c..df4ce03f2e 100644 --- a/troubleshoot/elasticsearch/painless-date-math-errors.md +++ b/troubleshoot/elasticsearch/painless-date-math-errors.md @@ -1,5 +1,10 @@ --- navigation_title: Date math errors +applies_to: + stack: ga + serverless: ga +products: + - id: elasticsearch --- # Troubleshoot date math errors in Painless diff --git a/troubleshoot/elasticsearch/painless-field-not-found.md b/troubleshoot/elasticsearch/painless-field-not-found.md index 287b37a65c..08e5d55703 100644 --- a/troubleshoot/elasticsearch/painless-field-not-found.md +++ b/troubleshoot/elasticsearch/painless-field-not-found.md @@ -1,5 +1,10 @@ --- navigation_title: Field not found (mapping conflicts) +applies_to: + stack: ga + serverless: ga +products: + - id: elasticsearch --- # Troubleshoot field not found (mapping conflicts) in Painless diff --git a/troubleshoot/elasticsearch/painless-ingest-pipeline-failures.md b/troubleshoot/elasticsearch/painless-ingest-pipeline-failures.md index f0d9e2effc..3558f1707e 100644 --- a/troubleshoot/elasticsearch/painless-ingest-pipeline-failures.md +++ b/troubleshoot/elasticsearch/painless-ingest-pipeline-failures.md @@ -1,5 +1,10 @@ --- navigation_title: Ingest pipeline failures +applies_to: + stack: ga + serverless: ga +products: + - id: elasticsearch --- # Troubleshoot ingest pipeline failures in Painless diff --git a/troubleshoot/elasticsearch/painless-null-pointer-exceptions.md b/troubleshoot/elasticsearch/painless-null-pointer-exceptions.md index 8d78cdfec1..de8be52ee5 100644 --- a/troubleshoot/elasticsearch/painless-null-pointer-exceptions.md +++ b/troubleshoot/elasticsearch/painless-null-pointer-exceptions.md @@ -1,5 +1,10 @@ --- navigation_title: Null pointer exceptions +applies_to: + stack: ga + serverless: ga +products: + - id: elasticsearch --- # Troubleshoot null pointer exceptions in Painless diff --git a/troubleshoot/elasticsearch/painless-regex-pattern-matching-failures.md b/troubleshoot/elasticsearch/painless-regex-pattern-matching-failures.md index c96a4d5e84..a0d4bf80fb 100644 --- a/troubleshoot/elasticsearch/painless-regex-pattern-matching-failures.md +++ b/troubleshoot/elasticsearch/painless-regex-pattern-matching-failures.md @@ -1,5 +1,10 @@ --- navigation_title: Regex pattern matching failures +applies_to: + stack: ga + serverless: ga +products: + - id: elasticsearch --- # Troubleshoot regex pattern matching failures in Painless diff --git a/troubleshoot/elasticsearch/painless-runtime-field-exceptions.md b/troubleshoot/elasticsearch/painless-runtime-field-exceptions.md index 9809489a63..040eb95080 100644 --- a/troubleshoot/elasticsearch/painless-runtime-field-exceptions.md +++ b/troubleshoot/elasticsearch/painless-runtime-field-exceptions.md @@ -1,5 +1,10 @@ --- navigation_title: Runtime field exceptions +applies_to: + stack: ga + serverless: ga +products: + - id: elasticsearch --- # Troubleshoot runtime field exceptions in Painless diff --git a/troubleshoot/elasticsearch/painless-sandbox-limitations.md b/troubleshoot/elasticsearch/painless-sandbox-limitations.md index c67d955e66..0e4c192266 100644 --- a/troubleshoot/elasticsearch/painless-sandbox-limitations.md +++ b/troubleshoot/elasticsearch/painless-sandbox-limitations.md @@ -1,5 +1,10 @@ --- navigation_title: Sandbox limitations +applies_to: + stack: ga + serverless: ga +products: + - id: elasticsearch --- # Troubleshoot sandbox limitations in Painless diff --git a/troubleshoot/elasticsearch/painless-script-score-calculation-errors.md b/troubleshoot/elasticsearch/painless-script-score-calculation-errors.md index d5d716f6d0..85babd3604 100644 --- a/troubleshoot/elasticsearch/painless-script-score-calculation-errors.md +++ b/troubleshoot/elasticsearch/painless-script-score-calculation-errors.md @@ -1,5 +1,10 @@ --- navigation_title: Script score calculation errors +applies_to: + stack: ga + serverless: ga +products: + - id: elasticsearch --- # Troubleshoot script score calculation errors in Painless diff --git a/troubleshoot/elasticsearch/painless-scripting.md b/troubleshoot/elasticsearch/painless-scripting.md index eea39dd251..83017c3962 100644 --- a/troubleshoot/elasticsearch/painless-scripting.md +++ b/troubleshoot/elasticsearch/painless-scripting.md @@ -1,5 +1,10 @@ --- navigation_title: Painless scripting +applies_to: + stack: ga + serverless: ga +products: + - id: elasticsearch --- # Troubleshoot Painless scripting in {{es}} diff --git a/troubleshoot/elasticsearch/painless-subfield-access.md b/troubleshoot/elasticsearch/painless-subfield-access.md index f39c019321..b494c42875 100644 --- a/troubleshoot/elasticsearch/painless-subfield-access.md +++ b/troubleshoot/elasticsearch/painless-subfield-access.md @@ -1,5 +1,10 @@ --- navigation_title: Subfield access +applies_to: + stack: ga + serverless: ga +products: + - id: elasticsearch --- # Troubleshoot subfield access in Painless diff --git a/troubleshoot/elasticsearch/painless-type-casting-issues.md b/troubleshoot/elasticsearch/painless-type-casting-issues.md index 1a41c4a81d..7cb9ca140a 100644 --- a/troubleshoot/elasticsearch/painless-type-casting-issues.md +++ b/troubleshoot/elasticsearch/painless-type-casting-issues.md @@ -1,5 +1,10 @@ --- navigation_title: Type casting issues +applies_to: + stack: ga + serverless: ga +products: + - id: elasticsearch --- # Troubleshoot type casting issues in Painless From 766c5a836e9456086ffc12abe67efb6ad81c5ef2 Mon Sep 17 00:00:00 2001 From: David Kilfoyle Date: Fri, 24 Oct 2025 15:15:00 -0400 Subject: [PATCH 3/5] Fix regex link --- .../elasticsearch/painless-regex-pattern-matching-failures.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/troubleshoot/elasticsearch/painless-regex-pattern-matching-failures.md b/troubleshoot/elasticsearch/painless-regex-pattern-matching-failures.md index a0d4bf80fb..9d1b7b7a3f 100644 --- a/troubleshoot/elasticsearch/painless-regex-pattern-matching-failures.md +++ b/troubleshoot/elasticsearch/painless-regex-pattern-matching-failures.md @@ -9,7 +9,7 @@ products: # Troubleshoot regex pattern matching failures in Painless -Follow these guidelines to avoid [regex](elasticsearch://reference/scripting-languages/painless/painless-regexes) operation errors in your Painless script. +Follow these guidelines to avoid [regex](elasticsearch://reference/scripting-languages/painless/painless-regexes.md) operation errors in your Painless script. ## Regex compilation and usage errors in Painless scripts From 973939e166f304b80675eb7efc6c7dec44fa4709 Mon Sep 17 00:00:00 2001 From: David Kilfoyle Date: Thu, 30 Oct 2025 16:15:55 -0400 Subject: [PATCH 4/5] edit --- ...painless-array-list-manipulation-errors.md | 30 ++++++------- .../painless-date-math-errors.md | 20 ++++----- .../elasticsearch/painless-field-not-found.md | 44 +++++++++---------- .../painless-ingest-pipeline-failures.md | 24 +++++----- .../painless-null-pointer-exceptions.md | 17 +++---- ...ainless-regex-pattern-matching-failures.md | 24 ++++------ .../painless-runtime-field-exceptions.md | 23 +++++----- .../painless-sandbox-limitations.md | 19 +++----- ...ainless-script-score-calculation-errors.md | 24 +++++----- .../elasticsearch/painless-scripting.md | 2 +- .../elasticsearch/painless-subfield-access.md | 26 +++++------ .../painless-type-casting-issues.md | 26 +++++------ 12 files changed, 119 insertions(+), 160 deletions(-) diff --git a/troubleshoot/elasticsearch/painless-array-list-manipulation-errors.md b/troubleshoot/elasticsearch/painless-array-list-manipulation-errors.md index ecde8f7638..887c5bffab 100644 --- a/troubleshoot/elasticsearch/painless-array-list-manipulation-errors.md +++ b/troubleshoot/elasticsearch/painless-array-list-manipulation-errors.md @@ -7,15 +7,13 @@ products: - id: elasticsearch --- -# Troubleshoot array/list manipulation errors in Painless +# Troubleshoot array manipulation errors in Painless -Follow these guidelines to avoid array access errors in your Painless script. +Follow these guidelines to avoid array (list) access errors in your Painless scripts. -## Array index\_out\_of\_bounds\_exception +An array `index_out_of_bounds_exception` occurs when a script tries to access an element at a position that does not exist in the array. For example, if an array has two elements, trying to access a third element triggers this exception. -Array index out of bounds exceptions occur when a script tries to access an element at a position that does not exist in the array. For example, if an array has two elements, trying to access a third element will trigger this exception. - -### Sample error +## Sample error ```json { @@ -71,7 +69,7 @@ Array index out of bounds exceptions occur when a script tries to access an elem } ``` -### Problematic code +## Problematic code ```json { @@ -92,13 +90,13 @@ Array index out of bounds exceptions occur when a script tries to access an elem } ``` -### Root cause +## Root cause The error occurs because the script tries to access index 2 (the third element) in an array that only has two elements (indices 0, 1). Arrays in Painless are zero-indexed, so accessing an index greater than or equal to the array size causes an exception. -### Solution: Check array bounds before accessing +## Solution: Check array bounds before accessing -Always verify array size before accessing specific indices: +Always verify the size of an array before accessing specific indices: ```json GET blog_posts/_search @@ -125,7 +123,7 @@ GET blog_posts/_search } ``` -### Sample document +## Sample document ```json POST blog_posts/_doc @@ -136,7 +134,7 @@ POST blog_posts/_doc } ``` -### Results +## Results ```json { @@ -159,8 +157,8 @@ POST blog_posts/_doc } ``` -### Notes +## Notes -* **Array bounds:** Always check array size before accessing specific indices. -* **Zero-indexed:** Remember that arrays start at index 0, so size() \- 1 is the last valid index. -* **Empty arrays:** Handle cases where arrays might be completely empty (size() \== 0). +* **Array bounds:** Always check the size of an array before accessing specific indices. +* **Zero-indexed:** Remember that arrays start at index 0, so `size() - 1` is the last valid index. +* **Empty arrays:** Handle cases where arrays might be completely empty (`size() == 0`). diff --git a/troubleshoot/elasticsearch/painless-date-math-errors.md b/troubleshoot/elasticsearch/painless-date-math-errors.md index df4ce03f2e..6c500f5224 100644 --- a/troubleshoot/elasticsearch/painless-date-math-errors.md +++ b/troubleshoot/elasticsearch/painless-date-math-errors.md @@ -9,15 +9,11 @@ products: # Troubleshoot date math errors in Painless -Follow these guidelines to avoid [date](elasticsearch://reference/scripting-languages/painless/using-datetime-in-painless.md) operation errors in your Painless script. +Follow these guidelines to avoid [date](elasticsearch://reference/scripting-languages/painless/using-datetime-in-painless.md) operation errors in your Painless scripts. -## Runtime mappings context +When you work with date fields in runtime mappings, accessing methods directly on the document field object can cause errors if the proper value accessor is not used. -### Dynamic method not found error - -When working with date fields in runtime mappings, accessing methods directly on the document field object can cause errors if the proper value accessor is not used. - -### Error +## Error ```json { @@ -76,7 +72,7 @@ When working with date fields in runtime mappings, accessing methods directly on } ``` -### Problematic code +## Problematic code ```json "script": { @@ -88,11 +84,11 @@ When working with date fields in runtime mappings, accessing methods directly on } ``` -### Root cause +## Root cause The script attempts to call `toInstant()` directly on a `ScriptDocValues.Dates` object. Date fields in Painless require accessing the `.value` property to get the actual date value before calling date methods. -### Solution +## Solution Access the date value using `.value` before calling date methods: @@ -100,13 +96,13 @@ Access the date value using `.value` before calling date methods: "script": { "lang": "painless", "source": """ - def orderDate = doc['order_date'].value; // added .value here + def orderDate = doc['order_date'].value; // Appended `.value` to the method. emit(orderDate.toInstant().toEpochMilli() + 14400000); """ } ``` -### Notes +## Notes * Always use `.value` when accessing single values from document fields in Painless. * Check for empty fields when the field might not exist in all documents. diff --git a/troubleshoot/elasticsearch/painless-field-not-found.md b/troubleshoot/elasticsearch/painless-field-not-found.md index 08e5d55703..7821e3b7c7 100644 --- a/troubleshoot/elasticsearch/painless-field-not-found.md +++ b/troubleshoot/elasticsearch/painless-field-not-found.md @@ -1,5 +1,5 @@ --- -navigation_title: Field not found (mapping conflicts) +navigation_title: Field not found errors applies_to: stack: ga serverless: ga @@ -7,15 +7,13 @@ products: - id: elasticsearch --- -# Troubleshoot field not found (mapping conflicts) in Painless +# Troubleshoot field not found errors in Painless -Follow these guidelines to avoid field access errors in your Painless script. +Follow these guidelines to avoid field access errors in your Painless scripts. -## A document doesn't have a value for a field +When you work with document fields, attempting to access fields that don't exist in all documents or aren't properly mapped leads to field not found exceptions, causing script failures. -When working with document fields, attempting to access fields that don't exist in all documents or aren't properly mapped leads to field not found exceptions, causing script failures. - -### Sample error +## Sample error ```json { @@ -78,7 +76,7 @@ When working with document fields, attempting to access fields that don't exist } ``` -### Problematic code +## Problematic code ```json { @@ -98,13 +96,13 @@ When working with document fields, attempting to access fields that don't exist } ``` -### Root cause +## Root cause A field not found exception occurs when a script tries to access a field that is not defined in the index mappings. If the field is defined in the mappings but has no value in some documents, the script will not fail as long as you first check whether the field has values. -For example, calling `doc['author_score'].value` directly on a document without that field will cause an error. The recommended approach is to use `doc[].size()==0` to check if the field is missing in a document before accessing its value. +For example, calling `doc['author_score'].value` directly on a document that does not contain that field causes an error. The recommended approach is to use `doc[].size()==0` to check if the field is missing in a document before accessing its value. -### Sample documents +## Sample documents ```json POST articles/_doc @@ -123,9 +121,9 @@ POST articles/_doc } ``` -### Solution 1: Check field existence before accessing +## Solution 1: Check field existence before accessing -Always verify field existence using `size()` before accessing field values: +Always verify the existence of a field by using `size()` before accessing field values: ```json GET articles/_search @@ -152,9 +150,9 @@ GET articles/_search } ``` -### Solution 2: New field API approach +## Solution 2: New field API approach -The [field API](/explore-analyze/scripting/script-fields-api.md) provides a more elegant solution that handles missing values automatically by allowing you to specify default values. This approach is more concise and eliminates the need for explicit field existence checks: +The [field API](/explore-analyze/scripting/script-fields-api.md) provides a more elegant solution that handles missing values automatically, by allowing you to specify default values. This approach is more concise and eliminates the need for explicit field existence checks: ```json GET articles/_search @@ -178,9 +176,9 @@ GET articles/_search } ``` -### Solution 3: Use the $ shortcut in field API syntax +## Solution 3: Use the $ shortcut in field API syntax -With the field API you can make the solution even more concise using the `$` shortcut: +With the field API, you can make the solution even more concise using the `$` shortcut: ```json GET articles/_search @@ -204,7 +202,7 @@ GET articles/_search } ``` -### Results +## Results ```json { @@ -238,12 +236,10 @@ GET articles/_search } ``` -### Notes +## Notes -* **Field presence:** Always check if fields exist before accessing them using `.size() > 0`. +* **Field presence:** Always check if fields exist before accessing them, using `.size() > 0`. * **Document variation:** Not all documents are guaranteed to have the same field structure. * **Mapping awareness:** A field must be defined in the index mappings to be accessed with doc values, and its value in each document must be validated. -* **Field API:** The `field` API and `$` shortcut handle missing values gracefully with default values. -* **Compatibility:** Some field types (like `text` or `geo`) [aren't yet supported](/explore-analyze/scripting/script-fields-api.md#_supported_mapped_field_types) by the field API; continue using `doc` for those. - - +* **Field API:** The `field` API and `$` shortcut handle missing values gracefully, using default values. +* **Compatibility:** Some field types (such as `text` or `geo`) [aren't yet supported](/explore-analyze/scripting/script-fields-api.md#_supported_mapped_field_types) by the field API; continue using `doc` for those. diff --git a/troubleshoot/elasticsearch/painless-ingest-pipeline-failures.md b/troubleshoot/elasticsearch/painless-ingest-pipeline-failures.md index 3558f1707e..193f76340f 100644 --- a/troubleshoot/elasticsearch/painless-ingest-pipeline-failures.md +++ b/troubleshoot/elasticsearch/painless-ingest-pipeline-failures.md @@ -9,15 +9,11 @@ products: # Troubleshoot ingest pipeline failures in Painless -Follow these guidelines to avoid [ingest pipeline](elasticsearch://reference/scripting-languages/painless/painless-ingest-processor-context.md) script errors in your Painless script. +Follow these guidelines to avoid [ingest pipeline](elasticsearch://reference/scripting-languages/painless/painless-ingest-processor-context.md) errors in your Painless scripts. -## Date conversion +When you convert time strings to nanoseconds in ingest pipelines, attempting to perform arithmetic operations directly on string values without proper date parsing causes type casting errors. -### Class cast exception when converting date data types - -When converting time strings to nanoseconds in ingest pipelines, attempting to perform arithmetic operations directly on string values without proper date parsing leads to type casting errors. - -### Sample error +## Sample error ```json { @@ -64,7 +60,7 @@ When converting time strings to nanoseconds in ingest pipelines, attempting to p } ``` -### Problematic code +## Problematic code ```json { @@ -76,11 +72,11 @@ When converting time strings to nanoseconds in ingest pipelines, attempting to p } ``` -### Root cause +## Root cause -When accessing fields via `ctx.time_field` in ingest pipelines, the values are not automatically parsed to their mapped field types. The script attempts to multiply a string value (time field) directly with an integer. Time strings like `"00:00:00.022"` remain as strings and need to be properly parsed as dates and converted to epoch milliseconds before performing arithmetic operations. +When accessing fields using `ctx.time_field` in ingest pipelines, the values are not automatically parsed to their mapped field types. The script attempts to multiply a string value (time field) directly with an integer. Time strings such as `"00:00:00.022"` remain as strings. They need to be properly parsed as dates and converted to epoch milliseconds before performing arithmetic operations. -### Solution: Use `SimpleDateFormat` in the script processor +## Solution: Use `SimpleDateFormat` in the script processor Parse the time string directly using SimpleDateFormat and get epoch milliseconds: @@ -113,7 +109,7 @@ POST _ingest/pipeline/_simulate } ``` -### Result +## Result ```json { @@ -136,7 +132,7 @@ POST _ingest/pipeline/_simulate } ``` -### Note +## Notes -* Time strings like `"HH:mm:ss.SSS"` must be explicitly parsed before arithmetic operations. +* Time strings such as `"HH:mm:ss.SSS"` must be explicitly parsed before performaing arithmetic operations. * Using `SimpleDateFormat` in a script processor allows custom parsing. diff --git a/troubleshoot/elasticsearch/painless-null-pointer-exceptions.md b/troubleshoot/elasticsearch/painless-null-pointer-exceptions.md index de8be52ee5..b57084d231 100644 --- a/troubleshoot/elasticsearch/painless-null-pointer-exceptions.md +++ b/troubleshoot/elasticsearch/painless-null-pointer-exceptions.md @@ -9,17 +9,11 @@ products: # Troubleshoot null pointer exceptions in Painless -Follow these guidelines to avoid null pointer exceptions in your Painless script. +Follow these guidelines to avoid null pointer exceptions in your Painless scripts. -## Null\_pointer\_exception +In Painless, field access methods vary depending on the script execution [context](elasticsearch://reference/scripting-languages/painless/painless-contexts.md). Using a field access pattern that is not valid for the current script context causes a `null_pointer_exception`. -Null pointer exceptions in Painless scripts often occur due to using field access patterns that are not valid for the current script context. - -### Wrong field access patterns in script contexts - -When writing Painless scripts in different [contexts](elasticsearch://reference/scripting-languages/painless/painless-contexts.md), using wrong field access patterns leads to null pointer exceptions because field access methods vary depending on the script execution context. - -### Sample error +## Sample error ```json { @@ -109,7 +103,8 @@ POST products/_doc ### Root cause -A common cause of null pointer exceptions in Painless scripts is attempting to access document fields using incorrect access patterns for the specific [script context](elasticsearch://reference/scripting-languages/painless/painless-contexts.md). In Painless, field access methods are context-dependent. For more information, refer to "Painless syntax-context bridge" in the Explore and Analyze documentation. +A common cause of null pointer exceptions in Painless scripts is attempting to access document fields using incorrect access patterns for the specific [script context](elasticsearch://reference/scripting-languages/painless/painless-contexts.md). To learn more about the context-dependent field access methods in Painless, refer to Painless syntax-context bridge in the Explore and Analyze documentation. +% Link to come after E&A PR is merged. The error occurs because `params['_source']` is not available in script filter contexts. In script filters, field values must be accessed through `doc` values, not through the `params['_source']` map. @@ -167,5 +162,3 @@ GET products/_search * **Context limitations:** Script filters cannot access `params['_source']` . * **Field mapping:** Use `.keyword` suffix for text fields when accessing via doc values. -For more details related to Painless context, refer to [Painless context documentation](elasticsearch://reference/scripting-languages/painless/painless-contexts.md) and Painless syntax-context bridge. - diff --git a/troubleshoot/elasticsearch/painless-regex-pattern-matching-failures.md b/troubleshoot/elasticsearch/painless-regex-pattern-matching-failures.md index 9d1b7b7a3f..f09c92a537 100644 --- a/troubleshoot/elasticsearch/painless-regex-pattern-matching-failures.md +++ b/troubleshoot/elasticsearch/painless-regex-pattern-matching-failures.md @@ -9,13 +9,11 @@ products: # Troubleshoot regex pattern matching failures in Painless -Follow these guidelines to avoid [regex](elasticsearch://reference/scripting-languages/painless/painless-regexes.md) operation errors in your Painless script. +Follow these guidelines to avoid [regex](elasticsearch://reference/scripting-languages/painless/painless-regexes.md) operation errors in your Painless scripts. -## Regex compilation and usage errors in Painless scripts +Regex operations in Painless can fail for several reasons: the regex feature is disabled, there is incorrect matcher usage, or there are malformed regex patterns. This may occur when standard Java regex behavior is thought to apply directly to Painless. -Regex operations in Painless can fail for several reasons: the regex feature is disabled, there is incorrect matcher usage, or there are malformed regex patterns. These errors are common when developers assume that standard Java regex behavior applies directly to Painless. - -### Sample error +## Sample error ```json { @@ -65,7 +63,7 @@ Regex operations in Painless can fail for several reasons: the regex feature is } ``` -### Problematic code +## Problematic code ```json { @@ -80,11 +78,11 @@ Regex operations in Painless can fail for several reasons: the regex feature is } ``` -### Root cause +## Root cause The error occurs because the `group()` method is called on a Matcher before calling `find()`. You must explicitly search for matches before accessing groups. This is a common mistake when developers expect the matcher to automatically find matches. -### Solution: Call find() before accessing groups +## Solution: Call find() before accessing groups Always call `find()` before using `group()` methods: @@ -105,7 +103,7 @@ POST _scripts/painless/_execute } ``` -### Results +## Results ```json { @@ -113,13 +111,9 @@ POST _scripts/painless/_execute } ``` -### Notes +## Notes * **Call find() first:** Always use `matcher.find()` before accessing groups. * **Enable regex:** Set `script.painless.regex.enabled=true` in the `elasticsearch.yml` settings file if regex is disabled. -* **Group numbering:** Use `group(0)` for the entire match, `group(1)` for first capture group, etc. +* **Group numbering:** Use `group(0)` for the entire match, `group(1)` for first capture group, and so on. * **Performance impact:** Regex operations can be expensive, especially with complex patterns. - - - - diff --git a/troubleshoot/elasticsearch/painless-runtime-field-exceptions.md b/troubleshoot/elasticsearch/painless-runtime-field-exceptions.md index 040eb95080..262740715c 100644 --- a/troubleshoot/elasticsearch/painless-runtime-field-exceptions.md +++ b/troubleshoot/elasticsearch/painless-runtime-field-exceptions.md @@ -9,15 +9,13 @@ products: # Troubleshoot runtime field exceptions in Painless -Follow these guidelines to avoid [runtime field](elasticsearch://reference/scripting-languages/painless/painless-runtime-fields-context.md) exceptions in your Painless script. +Follow these guidelines to avoid [runtime field](elasticsearch://reference/scripting-languages/painless/painless-runtime-fields-context.md) exceptions in your Painless scripts. -## Runtime mappings +## Using `return` instead of `emit` in runtime field in runtime mappings -### Using return instead of emit in runtime field +When you create runtime mappings in a Painless script, using `return` instead of `emit` to output values leads to compilation errors, as runtime field scripts require the `emit()` function to produce field values. -When creating runtime mappings, using `return` instead of `emit` to output values leads to compilation errors, as runtime field scripts require the `emit()` function to produce field values. - -### Sample error +## Sample error ```json { @@ -74,7 +72,7 @@ When creating runtime mappings, using `return` instead of `emit` to output value } ``` -### Problematic code +## Problematic code ```json { @@ -94,11 +92,11 @@ When creating runtime mappings, using `return` instead of `emit` to output value } ``` -### Root cause +## Root cause -Runtime field scripts use `emit()` to produce values, not `return`. The `emit()` function is specifically designed for runtime mappings to output field values, while `return` is used in other Painless contexts like script queries or update scripts. The error occurs because runtime field scripts expect void return type, but the script attempts to return a String value. +Runtime field scripts use `emit()` to produce values, rather than `return`. The `emit()` function is specifically designed for runtime mappings to output field values, while `return` is used in other Painless contexts such as script queries or update scripts. The error occurs because runtime field scripts expect a void return type, but the script attempts to return a String value. -### Solution: Replace return with emit +## Solution: Replace return with emit Replace `return` statements with `emit()` calls: @@ -127,7 +125,7 @@ POST users/_search } ``` -### Results +## Results ```json { @@ -159,8 +157,7 @@ POST users/_search } ``` -### Notes +## Notes * Runtime field scripts must use `emit()` to output values, not `return`. * `emit()` can be called multiple times in a script to emit multiple values. - diff --git a/troubleshoot/elasticsearch/painless-sandbox-limitations.md b/troubleshoot/elasticsearch/painless-sandbox-limitations.md index 0e4c192266..d76497f7c2 100644 --- a/troubleshoot/elasticsearch/painless-sandbox-limitations.md +++ b/troubleshoot/elasticsearch/painless-sandbox-limitations.md @@ -11,11 +11,9 @@ products: Follow these guidelines to avoid Painless sandbox restriction errors in your script. -## Painless sandbox restrictions causing compilation errors +Painless implements sandbox limitations that differ from standard Java syntax and behavior. These restrictions are designed to optimize performance and prevent logical errors, which can lead to unexpected compilation errors when common Java patterns are used. One limitation is that empty `foreach` loops are not allowed. -Painless implements sandbox limitations that differ from standard Java syntax and behavior. These restrictions are designed to optimize performance and prevent logical errors, which can lead to unexpected compilation errors when developers use common Java patterns. One limitation is that empty foreach loops are not allowed. - -### Sample error +## Sample error ```json { @@ -83,7 +81,7 @@ Painless implements sandbox limitations that differ from standard Java syntax an } ``` -### Problematic code +## Problematic code ```json { @@ -104,12 +102,11 @@ Painless implements sandbox limitations that differ from standard Java syntax an } ``` -### Root cause +## Root cause -* **Empty loop blocks:** Painless does not allow empty foreach loops as an intentional feature to enhance usability and performance. +* **Empty loop blocks:** Painless does not allow empty `foreach` loops as an intentional feature to enhance usability and performance. * **Performance optimization:** Since scripts run once per document and there may be millions of documents, empty loops are considered wasteful. - The error occurs because Painless expects meaningful code inside loop blocks and treats empty loops as potential bugs or risks. ### Solution: Add code inside loop blocks @@ -136,9 +133,7 @@ POST _scripts/painless/_execute } ``` -### Notes +## Notes -* **Empty loops:** Painless intentionally prohibits empty foreach loops for performance reasons. +* **Empty loops:** Painless intentionally prohibits empty `foreach` loops for performance reasons. * **Syntax differences:** Painless syntax differs from Java in several ways to optimize execution and prevent logical errors. - - diff --git a/troubleshoot/elasticsearch/painless-script-score-calculation-errors.md b/troubleshoot/elasticsearch/painless-script-score-calculation-errors.md index 85babd3604..44d3a66665 100644 --- a/troubleshoot/elasticsearch/painless-script-score-calculation-errors.md +++ b/troubleshoot/elasticsearch/painless-script-score-calculation-errors.md @@ -9,14 +9,12 @@ products: # Troubleshoot script score calculation errors in Painless -Follow these guidelines to avoid scoring calculation errors in your Painless script. +Follow these guidelines to avoid scoring calculation errors in your Painless scripts. -## script\_score script returned an invalid score +When you use [`script_score`](elasticsearch://reference/query-languages/query-dsl/query-dsl-script-score-query.md) with type `double`, + the script can return unexpected null values, negative values `0.0`, or Infinity, causing documents to receive a score of `0` or be excluded from results entirely. This commonly occurs when field access patterns don't account for missing values or when mathematical operations result in null propagation. -When using [`script_score`](elasticsearch://reference/query-languages/query-dsl/query-dsl-script-score-query.md) with type `double`, - it can return unexpected null values, negative values `0.0` or Infinity, causing documents to receive a score of `0` or be excluded from results entirely. This commonly occurs when field access patterns don't account for missing values or when mathematical operations result in null propagation. - -### Sample error +## Sample error ```json { @@ -55,7 +53,7 @@ When using [`script_score`](elasticsearch://reference/query-languages/query-dsl/ } ``` -### Problematic code +## Problematic code ```json { @@ -78,12 +76,12 @@ When using [`script_score`](elasticsearch://reference/query-languages/query-dsl/ } ``` -### Root cause +## Root cause The error occurs because of mathematical edge cases in calculations: 1. **Math.log() with zero or negative values:** `Math.log(0)` returns negative infinity, `Math.log(-x)` returns `NaN`. -2. **Division by zero:** Operations like `x/0` throw an arithmetic\_exception. +2. **Division by zero:** Operations such as `x/0` throw an `arithmetic_exception`. 3. **NaN propagation:** Any mathematical operation involving `NaN` results in `NaN`. 4. **Infinity calculations:** Operations with infinity often result in `NaN` or unexpected values. @@ -118,7 +116,7 @@ GET products/_search return 1.0; } - return Math.max(score, 0.1); // Ensure minimum positive score + return Math.max(score, 0.1); // Ensure a minimum positive score """ } } @@ -126,7 +124,7 @@ GET products/_search } ``` -### Sample documents +## Sample documents ```json POST products/_doc @@ -146,7 +144,7 @@ POST products/_doc } ``` -### Results +## Results ```json { @@ -181,7 +179,7 @@ POST products/_doc } ``` -### Notes +## Notes * **Mathematical safety:** Validate inputs for functions like `Math.log()`. * **Default values:** Provide meaningful defaults for missing fields to maintain consistent scoring. diff --git a/troubleshoot/elasticsearch/painless-scripting.md b/troubleshoot/elasticsearch/painless-scripting.md index 83017c3962..7b46c1ff83 100644 --- a/troubleshoot/elasticsearch/painless-scripting.md +++ b/troubleshoot/elasticsearch/painless-scripting.md @@ -9,7 +9,7 @@ products: # Troubleshoot Painless scripting in {{es}} -Use the topics in this section to troubleshoot common errors in your [Painless scripts](/explore-analyze/scripting/modules-scripting-painless.md). +Use the topics in this section to troubleshoot common errors in your [Painless](/explore-analyze/scripting/modules-scripting-painless.md) scripts. * [Array/list manipulation errors](/troubleshoot/elasticsearch/painless-array-list-manipulation-errors.md) * [Date math errors](/troubleshoot/elasticsearch/painless-date-math-errors.md) diff --git a/troubleshoot/elasticsearch/painless-subfield-access.md b/troubleshoot/elasticsearch/painless-subfield-access.md index b494c42875..b3d85a76d6 100644 --- a/troubleshoot/elasticsearch/painless-subfield-access.md +++ b/troubleshoot/elasticsearch/painless-subfield-access.md @@ -9,13 +9,11 @@ products: # Troubleshoot subfield access in Painless -Follow these guidelines to avoid nested field access errors in your Painless script. +Follow these guidelines to avoid nested field access errors in your Painless scripts. -## No field found for \[field\] in mapping +When you access subfields using the doc accessor, using incorrect syntax or trying to access non-existent fields without proper validation leads to runtime errors. -When accessing subfields through doc accessor, using incorrect syntax or trying to access non-existent fields without proper validation leads to runtime errors. - -### Sample error +## Sample error ```json { @@ -80,9 +78,9 @@ When accessing subfields through doc accessor, using incorrect syntax or trying } ``` -### Problematic approaches +## Problematic approaches -Following are some common incorrect ways to access subfields: +The following two methods of accessing subfields will result in errors: ```json { @@ -122,7 +120,7 @@ Or: } ``` -### Sample data +## Sample data ```json PUT events/_doc/1 @@ -149,13 +147,13 @@ PUT events/_doc/3 } ``` -### Root cause +## Root cause -When accessing subfields in Painless scripts using the `doc` accessor, the correct syntax requires using the full dot notation path as a single string (`doc['parent.child’]`), not as a separate property access or bracket notation. This applies to all Painless contexts where `doc` accessor is available, including runtime mapping, script queries, aggregations, and ingest processors. +When accessing subfields in Painless scripts using the `doc` accessor, the correct syntax requires using the full dot notation path as a single string (`doc['parent.child’]`), rather than as a separate property access or bracket notation. This applies to all Painless contexts where `doc` accessor is available, including runtime mapping, script queries, aggregations, and ingest processors. The error occurs because `doc[‘event’]` attempts to find a field named “event” rather than accessing subfields within the event object. -### Solution: Correct subfield access with validation +## Solution: Correct subfield access with validation Use full dot notation and validate that the field exists:: @@ -188,7 +186,7 @@ POST events/_search } ``` -### Results +## Results ```json { @@ -280,9 +278,9 @@ POST events/_search } ``` -### Notes +## Notes -* Use full dot notation as a single string: `doc['parent.child’]` not `doc['parent.['child’].` +* Use full dot notation as a single string: `doc['parent.child’]` rather than `doc['parent.['child’].` * Always validate field existence using `.size() > 0` before accessing subfield values. * Field validation is crucial when documents have varying object structures. diff --git a/troubleshoot/elasticsearch/painless-type-casting-issues.md b/troubleshoot/elasticsearch/painless-type-casting-issues.md index 7cb9ca140a..1ba430ed49 100644 --- a/troubleshoot/elasticsearch/painless-type-casting-issues.md +++ b/troubleshoot/elasticsearch/painless-type-casting-issues.md @@ -9,13 +9,11 @@ products: # Troubleshoot type casting issues in Painless -Follow these guidelines to avoid type conversion errors in your Painless script. +Follow these guidelines to avoid type conversion errors in your Painless scripts. -## Cannot cast from \[type\_number\] to \[type\_number\] +When you perform [type casting](elasticsearch://reference/scripting-languages/painless/painless-casting.md) in Painless scripts, attempting implicit conversions or casting incompatible types without proper validation leads to compilation and runtime errors. -When performing [type casting](elasticsearch://reference/scripting-languages/painless/painless-casting.md) in Painless scripts, attempting implicit conversions or casting incompatible types without proper validation leads to compilation and runtime errors. - -### Sample error +## Sample error ```json { @@ -70,7 +68,7 @@ When performing [type casting](elasticsearch://reference/scripting-languages/pai } ``` -### Problematic code +## Problematic code ```json { @@ -90,7 +88,7 @@ When performing [type casting](elasticsearch://reference/scripting-languages/pai } ``` -### Sample data +## Sample data ```json PUT products/_doc/1 @@ -106,11 +104,11 @@ PUT products/_doc/2 } ``` -### Root cause +## Root cause -Painless has [specific rules](https://www.elastic.co/docs/reference/scripting-languages/painless/painless-casting) for implicit and explicit type casting between numeric types. While some numeric conversions are allowed implicitly (widening conversions like `int` into `double`), narrowing conversions like `double` to `int` require explicit casting. The script attempts to assign a `double` result to an `int` variable without explicit casting, which causes a compilation error since this is a narrowing conversion that could lose precision. Additionally, field values may be null or of unexpected types, requiring proper validation before casting. +Painless has [specific rules](https://www.elastic.co/docs/reference/scripting-languages/painless/painless-casting) for implicit and explicit type casting between numeric types. While some numeric conversions are allowed implicitly (widening conversions such as `int` into `double`), narrowing conversions such as `double` to `int` require explicit casting. The script attempts to assign a `double` result to an `int` variable without explicit casting, which causes a compilation error since this is a narrowing conversion that could lose precision. Additionally, field values may be null or of unexpected types, requiring proper validation before casting. -### Solution: Use explicit numeric type casting +## Solution: Use explicit numeric type casting Use explicit casting with proper validation: @@ -149,7 +147,7 @@ POST products/_search } ``` -### Results +## Results ```json { @@ -208,10 +206,10 @@ POST products/_search } ``` -### Notes +## Notes -* Validate field existence using `.size() > 0` before accessing values. +* Validate the existence of a field using `.size() > 0` before accessing values. * Check for null values using `value != null` before casting. * Use `instanceof Number` to verify the value is numeric before casting. * Handle missing fields gracefully with default values. -* When working with {{es}} field values, always validate the actual field type before assuming. +* When working with {{es}} field values, always validate the actual field type. From a796ad70df4439ef8db77b841c561936e5239487 Mon Sep 17 00:00:00 2001 From: David Kilfoyle Date: Thu, 30 Oct 2025 16:18:32 -0400 Subject: [PATCH 5/5] nav fix --- .../elasticsearch/painless-array-list-manipulation-errors.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/troubleshoot/elasticsearch/painless-array-list-manipulation-errors.md b/troubleshoot/elasticsearch/painless-array-list-manipulation-errors.md index 887c5bffab..a30ff995a5 100644 --- a/troubleshoot/elasticsearch/painless-array-list-manipulation-errors.md +++ b/troubleshoot/elasticsearch/painless-array-list-manipulation-errors.md @@ -1,5 +1,5 @@ --- -navigation_title: Array/list manipulation errors +navigation_title: Array manipulation errors applies_to: stack: ga serverless: ga