quickwit-oss/quickwit · error
QueryAst should be JSON serializable
Error message
QueryAst should be JSON serializable
What it means
The ListFields ES-compatible API serializes the parsed index_filter QueryAst to JSON to embed it in the gRPC ListFieldsRequest. QueryAst is guaranteed to be JSON-serializable by design, so a serialization failure indicates a bug in an AST node's Serialize impl and panics via expect.
Source
Thrown at quickwit/quickwit-serve/src/elasticsearch_api/model/field_capability.rs:224
ElasticsearchError::new(
StatusCode::BAD_REQUEST,
format!("Failed to convert index_filter: {err}"),
None,
)
})?;
Ok(Some(query_ast))
}
#[allow(clippy::result_large_err)]
pub fn build_list_field_request_for_es_api(
index_id_patterns: Vec<String>,
search_params: FieldCapabilityQueryParams,
search_body: FieldCapabilityRequestBody,
) -> Result<quickwit_proto::search::ListFieldsRequest, ElasticsearchError> {
let query_ast = parse_index_filter_to_query_ast(search_body.index_filter)?;
let query_ast_json = query_ast
.map(|ast| serde_json::to_string(&ast).expect("QueryAst should be JSON serializable"));
Ok(quickwit_proto::search::ListFieldsRequest {
index_id_patterns,
field_patterns: search_params.fields.unwrap_or_default(),
start_timestamp: search_params.start_timestamp,
end_timestamp: search_params.end_timestamp,
query_ast: query_ast_json,
limit: None,
})
}
#[cfg(test)]
mod tests {
use serde_json::json;
use super::*;
#[test]View on GitHub (pinned to a39730c5cd)
Solutions
- Check the index_filter JSON in the request is well-formed
- If you develop custom QueryAst nodes, verify their Serialize/Deserialize impls round-trip
- Pin/align quickwit-query versions across the workspace
Defensive patterns
Strategy: try-catch
Validate before calling
// Validate the index_filter body before the request:
let ast = serde_json::from_value::<serde_json::Value>(index_filter)?; // must be valid JSON
if !index_filter.is_object() { return Err(ElasticsearchError::invalid_argument("index_filter")); } Try / catch
// Callers of the list-fields ES API:
match resp {
Ok(fields) => fields,
Err(e) if e.status() == 400 => { /* fix index_filter JSON and retry */ }
Err(e) => return Err(e.into()),
} Prevention
- Send only well-formed boolean/term filters in _field_caps index_filter
- Round-trip test custom QueryAst Serialize/Deserialize impls
- Keep quickwit-query versions aligned
When it happens
Trigger: build_list_field_request_for_es_api with an index_filter whose QueryAst serde implementation fails (non-serializable value in a custom/new AST node).
Common situations: Adding new QueryAst node types without deriving/implementing Serialize correctly; extremely large or malformed index_filter bodies that hit serde limits.
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- Failed to serialize QueryAst
- `doc_batch` should not be empty
- node not found in pending
- OTP logs or traces do not support VRL transforms
- Encountered unknown command: code {other}
AI-assisted analysis of quickwit-oss/quickwit@a39730c5cd (2026-09-08).
Data as JSON: /api/errors/f0df9c50c51b989d.
Report an issue: GitHub.