Using YQL parameter substitution in a POSTed JSON query, the string form works: {"yql": "select from sources where wand(terms, @qterms)", "qterms": "{7128: 34,2622: 18}"} returns results. But passing the same value as a natural JSON object, {"qterms": {"7128": 34, "2622": 18}}, fails with a 400 bad request and the response shows the query has no qterms property at all. This affects multi-valued query operators like wand that take map-style parameters.
Vespa YQL parameter substitution fails with 400 when passing a JSON object in POST query
Root cause, diagnosed by maintainer pangwangshu: a query POSTed as JSON has its nested objects flattened into single-level dotted properties by Json2SingleLevelMap (this is what makes "ranking": {"profile": ...} work). So "qterms": {"7128": 34, "2622": 18} becomes qterms.7128 and qterms.2622, leaving no qterms property for YqlParser.addItems, which then passed a null lookup on and produced the 400. The fix is PR https://github.com/vespa-engine/vespa/pull/37759. Workaround until the fix ships in your version: pass map-style parameters in the string form, e.g. "q_terms": "{7128: 34, 2622: 18}". Source: https://github.com/vespa-engine/vespa/issues/29636
Source: https://github.com/vespa-engine/vespa/issues/29636