hcengineering/platform · error · Error

unknown operator: ${name}

Error message

unknown operator: ${name}

What it means

This error is thrown by the internal _getOperator lookup in the query engine when an update operator name is not present in the registered operators table. The library supports a fixed set of MongoDB-like operators ($set, $inc, $unset, $rename, etc.) and rejects anything else at query-build time. It means the query object contains a $-keyed field the engine does not recognize.

Source

Thrown at foundations/core/packages/core/src/operator.ts:213

/**
 * @public
 */
export function isOperator (o: Record<string, any>): boolean {
  if (o === null || typeof o !== 'object') {
    return false
  }
  const keys = Object.keys(o)
  return keys.length > 0 && keys.every((key) => key.startsWith('$'))
}

/**
 * @internal
 * @param name -
 * @returns
 */
export function _getOperator (name: string): _OperatorFunc {
  const operator = operators[name]
  if (operator === undefined) throw new Error('unknown operator: ' + name)
  return operator
}

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Check the operator name spelling and restrict updates to the operators registered in foundations/core/packages/core/src/operator.ts ($set, $inc, $unset, $rename, etc.).
  2. Replace unsupported operators with supported equivalents (e.g. emulate $push by reading the doc, modifying the array, and issuing $set).
  3. If the operator should exist, register it in the operators record or upgrade to a library version that supports it.
  4. Validate dynamically built update clauses with isOperator() plus an allow-list before passing them to the API.

Example fix

// before
await tx.update(doc, { $push: { tags: 'new' } })
// after
const tags = [...(doc.tags ?? []), 'new']
await tx.update(doc, { $set: { tags } })
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED = ['$set', '$inc', '$unset', '$rename'] // plus operators exported by the lib
function hasKnownOperators(update: Record<string, any>): boolean {
  return Object.keys(update).every((k) => SUPPORTED.includes(k))
}
if (!hasKnownOperators(updateClause)) throw new Error('unsupported update operator')

Type guard

function isKnownOperator(o: Record<string, any>): boolean {
  return isOperator(o) && Object.keys(o).every((k) => k in operatorsAllowList)
}

Try / catch

try {
  await update(doc, clause)
} catch (e) {
  if (e instanceof Error && e.message.startsWith('unknown operator:')) {
    console.error('Unsupported operator in', clause, e.message)
  } else throw e
}

Prevention

When it happens

Trigger: Calling an update/find-and-modify API with an update clause whose key is not one of the registered operators, e.g. { $push: {...} } or { $mul: {...} } when only $set/$inc/$unset/$rename are implemented. Also occurs on typos like { $st: ... } and on passing user-supplied operator names straight into the update object.

Common situations: Porting code written against MongoDB and assuming all Mongo operators ($push, $pull, $addToSet, $bit) exist; typos in operator names; dynamic construction of update clauses from user input or config where an unsupported operator slips in; library version differences where an operator was added later.

Related errors


AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29). Data as JSON: /api/errors/98631fbff8f7f9dd. Report an issue: GitHub.