Skip to content

Limits

Every structural limit the reference parser enforces, with the value and what happens when you cross it.

The reference parser allocates each query from a fixed-size arena, which is how it parses without touching the heap. Those fixed sizes are the language's practical limits, and every one of them is a query someone will eventually write.

None of these are configurable.

Hard limits

Crossing any of these rejects the query.

Limit Value Error
AST nodes per query 64 arena overflow: too many AST nodes (max 64)
Anchors per query 32 arena overflow: too many anchors (max 32)
String bytes per query 4096 arena overflow: string buffer exhausted (max 4096 bytes)
Elements in one vector literal 4096 vector too large (max 4096 elements)
Anchors in one list 8 too many anchors in list (max 8)
Namespace includes 8 too many namespace includes (max 8)
Namespace excludes 8 too many namespace excludes (max 8)
Expression nesting depth 128 expression nesting too deep (max 128)
Children per AND / OR node 16 structural — see below

"String bytes per query" is the total across every anchor and namespace name in the query, not per string. A query with twenty long phrase anchors can exhaust it even though no single anchor is close to the cap.

"Anchors in one list" applies separately to toward, attract and repel.

One soft limit

Limit Value Behaviour
Vector floats per query 8192 Falls back to a heap allocation

This one does not reject the query. When the vector arena is exhausted the parser allocates from the heap and carries on, so the only consequence is that the parse is no longer allocation-free.

It matters if you are relying on the zero-allocation property on a hot path, and not at all otherwise. Two 4096-element vector anchors reach it exactly.

The 16-child limit

A boolean node holds at most 16 children. There is no dedicated error message for exceeding it, because the parser builds AND and OR as nested binary nodes rather than one flat list — a 20-clause AND becomes a deeper tree, not an over-full node, and it is the 64-node or 128-depth limit you meet first.

The 16 matters when constructing JSON by hand: a single {"and": [...]} array with more than 16 entries has no valid parse.

Working within them

64 nodes is a lot of query. If you are approaching it, the usual cause is a generated OR over a list that grew — one clause per item in a catalogue, say. That shape is better served by a broader DIRECTION or a CONTRAST that names the shared quality, which is also more likely to match items nobody has added yet.