Description
When an error occurs in the if
statement of an ingest processor, and the processor has ignore_failure=true
, the failure is not ignored, and the on_failure processor is called. This behavior seems incorrect. Example:
Given the following pipeline:
{
"processors":
[
{
"set":
{
"if": "ctx.does_not_exist.length() > 0",
"ignore_failure": true,
"field": "wont_get_set",
"value": true
}
},
{
"set":
{
"field": "set_after",
"value": true
}
}
],
"on_failure":
[
{
"set":
{
"field": "error",
"value": "{{ _ingest.on_failure_message }}"
}
}
]
}'
And the following simulate ingest:
curl -s -X POST "localhost:9200/_ingest/pipeline/some_pipeline/_simulate?pretty" -H 'Content-Type: application/json' -d'
{
"docs": [
{
"_source": { "field": 1 }
}
]
}
'
We get the following output:
{
"docs": [
{
"doc": {
"_index": "_index",
"_version": "-3",
"_id": "_id",
"_source": {
"field": 1,
"error": "cannot access method/field [length] from a null def reference"
},
"_ingest": {
"timestamp": "2025-03-31T22:42:12.895010791Z"
}
}
}
]
}
This seems incorrect. Though the if
statement in the first processor should fail because the variable does_not_exist
does not exist, ignore_failure
was set to true. So the following set processor should have run, and set_after
field should be set. The failure processor should not have run.
The results should instead have been:
{
"field": 1,
"set_after": true
}
Interestingly, if verbose
is set to true in the simulate call, we get the correct result. I did a bit of debugging, and see that without verbose, the top-level CompoundProcessor has ignore_failure=false
. Whereas, with verbose, the top-level TrackingResultProcessor has ignore_failure=true
. It appears this this is because the tracking result processor unwraps the conditional processor here, bringing the ignore_failure
value up to the top-level processor.