{"record":{"id":"8d6f56a03e0a85e4","repo":"rolldown/rolldown","slug":"querykey-should-be-followed-by-queryvalue-but","errorCode":null,"errorMessage":"`QueryKey` should be followed by `QueryValue`, but got `{:?}`","messagePattern":"`QueryKey` should be followed by `QueryValue`, but got `(.+?)`","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/rolldown_binding/src/options/plugin/types/binding_filter_expression.rs","lineNumber":152,"sourceCode":"        ret.push(Token::And(take_payload(value)?.try_into_number()?));\n      }\n      FilterTokenKind::Or => {\n        ret.push(Token::Or(take_payload(value)?.try_into_number()?));\n      }\n      FilterTokenKind::Not => {\n        ret.push(Token::Not);\n      }\n      FilterTokenKind::Include => ret.push(Token::Include),\n      FilterTokenKind::Exclude => ret.push(Token::Exclude),\n      FilterTokenKind::CleanUrl => ret.push(Token::CleanUrl),\n      FilterTokenKind::QueryKey => {\n        let query_key = take_payload(value)?.try_into_string()?;\n        iter.next();\n        let next_token = iter.peek_mut().ok_or_else(|| {\n          anyhow::anyhow!(\"`QueryKey` should be followed by a `QueryValue` token\")\n        })?;\n        if next_token.kind != FilterTokenKind::QueryValue {\n          anyhow::bail!(\n            \"`QueryKey` should be followed by `QueryValue`, but got `{:?}`\",\n            next_token.kind\n          );\n        }\n        let query_value = match take_payload(next_token)? {\n          BindingFilterTokenPayloadInner::StringOrRegex(string_or_regex) => match string_or_regex {\n            StringOrRegex::String(str) => Token::String(str),\n            StringOrRegex::Regex(regexp) => Token::Regex(regexp),\n          },\n          BindingFilterTokenPayloadInner::Boolean(v) => Token::Boolean(v),\n          BindingFilterTokenPayloadInner::Number(_) => {\n            anyhow::bail!(\"number values are not supported for query filter values\");\n          }\n        };\n        ret.push(query_value);\n        ret.push(Token::String(query_key));\n        ret.push(Token::Query);\n        iter.next();","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/rolldown/rolldown/blob/91b44b9d7bcfb5725533478e044e3891a251b2c5/crates/rolldown_binding/src/options/plugin/types/binding_filter_expression.rs#L134-L170","documentation":"When normalizing filter-expression tokens, a `QueryKey` token must be immediately followed by a `QueryValue` token (e.g. `id` query key followed by its value). If the next token has a different kind, normalization fails with this error describing the actual next kind.","triggerScenarios":"Building a filter expression whose query part omits the value, e.g. an expression ending with a bare query key (`importerId?ext` without value), or a token array where the value token was dropped/mistyped so the next token is `QueryKey`, `String`, etc.","commonSituations":"Hand-writing query filters in `transformFilter`/hook filter expressions (`?` queries like `?query=value`) with a missing `=` value, or programmatic token arrays with dropped elements.","solutions":["Ensure every `QueryKey` token is immediately followed by a `QueryValue` token","Check the filter expression string for a query written as `?key` without `=value` and add the value","Verify programmatic token arrays are not missing elements (shifted kinds)","Inspect the reported `{:?}` kind in the message to see which wrong token followed"],"exampleFix":"// before\nfilters: [{ kind: 'importerId', query: { key: 'ext' } }] // missing value\n// after\nfilters: [{ kind: 'importerId', query: { key: 'ext', value: 'js' } }]","handlingStrategy":"validation","validationCode":"function validateQueryPairs(tokens) {\n  for (let i = 0; i < tokens.length; i++) {\n    if (tokens[i].kind === 'QueryKey' && tokens[i + 1]?.kind !== 'QueryValue') {\n      throw new Error(`QueryKey at ${i} not followed by QueryValue`);\n    }\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  const compiled = preCompileFilterExpr(tokens);\n} catch (e) {\n  if (String(e).includes('QueryKey')) console.error('Malformed query pair in filter expression:', e.message);\n  throw e;\n}","preventionTips":["Always write queries as key=value pairs, never bare keys","Build query tokens with a helper that always emits key+value together","Validate token arrays before calling the binding"],"tags":["filter-expression","query","plugin","validation","rust"],"backgroundTag":"invalid-argument-format","analyzedSha":"91b44b9d7bcfb5725533478e044e3891a251b2c5","analyzedAt":"2026-09-07T16:04:13.504Z","contentChangedAt":"2026-09-07T16:04:13.504Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}