krisk/Fuse · error · Error
Unknown query operator '${op}'
Error message
Unknown query operator '${op}' What it means
The operator wrapped by $not must be a known operator. When isKnownOperator(innerOp) is false, compileClause throws UNKNOWN_QUERY_OPERATOR with the inner operator's name. This is the negation-path check before an inverse matcher is looked up.
Source
Thrown at src/search/extended/objectQuery.ts:110
)
}
const innerOp = innerOps[0]
if (innerOp === NOT) {
throw new Error(
ErrorMsg.INVALID_FIELD_QUERY(keyPath, '$not cannot be nested')
)
}
if (innerOp === AND || innerOp === OR) {
throw new Error(
ErrorMsg.INVALID_FIELD_QUERY(
keyPath,
`${innerOp} cannot be used inside $not`
)
)
}
if (!isKnownOperator(innerOp)) {
throw new Error(ErrorMsg.UNKNOWN_QUERY_OPERATOR(innerOp))
}
// `$fuzzy` and `$eq` have no inverse matcher (fuzzy is graded rather than
// boolean; whole-string inequality is unimplemented, which is why `$ne`
// stays reserved). Report that distinctly from "unknown operator".
def = negatedMatcherDefForOperator(innerOp)
if (!def) {
throw new Error(
ErrorMsg.INVALID_FIELD_QUERY(
keyPath,
`'${innerOp}' cannot be negated`
)
)
}
raw = inner[innerOp]
valueOp = innerOp
} else {View on GitHub (pinned to edf2fb608e)
Solutions
- Fix the operator name inside $not to a supported one ($contains, $startsWith, $endsWith, $fuzzy, $eq, etc.)
- Check the library docs for the supported operator list — Mongo operators like $gt/$in are not available
- If queries come from persisted config, validate operator names against isKnownOperator before calling search
Example fix
// before
search({ title: { $not: { $gte: 'a' } } })
// after
search({ title: { $not: { $startsWith: 'a' } } }) Defensive patterns
Strategy: type-guard
Validate before calling
import { isKnownOperator } from './search/extended/matchers'
function validateNegatedOperator(clause) {
const inner = clause && clause.$not
if (inner) {
const op = Object.keys(inner)[0]
if (!isKnownOperator(op)) throw new Error(`Unknown operator '${op}' inside $not`)
}
} Type guard
function isKnownOperator(op) { return KNOWN_OPS.includes(op) } Try / catch
try {
results = search(query)
} catch (e) {
if (e.message.includes('Unknown query operator')) {
const op = e.message.match(/'([^']+)'/)?.[1]
throw new Error(`'${op}' is not supported — check the operator list (typos? Mongo ops?)`)
} else throw e
} Prevention
- Check operator names against the documented list
- Watch for Mongo/SQL operator leakage ($gte, $in, LIKE) into queries
- Validate persisted query configs after any library upgrade
When it happens
Trigger: search({ title: { $not: { $contins: 'a' } } }) — a typo'd or entirely unknown operator inside $not.
Common situations: Typos in operator names ($regex vs $regexx); using operators from another library (Mongo's $gte/$lte are not supported here); refactors that renamed operators while queries were stored as strings/config.
AI-assisted analysis of krisk/Fuse@edf2fb608e (2026-09-02).
Data as JSON: /api/errors/272775cf93e0feff.
Report an issue: GitHub.