{"record":{"id":"33b80b9ccfad3f95","repo":"payloadcms/payload","slug":"operator-handler-handler-name-returned-an-inv","errorCode":null,"errorMessage":"Operator handler \"${handler.name}\" returned an invalid operand transform for the \"${resolvedOperator}\" operator at path \"${path}\". Expected an object with \"column\" and \"value\" properties.","messagePattern":"Operator handler \"(.+?)\" returned an invalid operand transform for the \"(.+?)\" operator at path \"(.+?)\"\\. Expected an object with \"column\" and \"value\" properties\\.","errorType":"http","errorClass":"APIError","httpStatus":500,"severity":"error","filePath":"packages/drizzle/src/queries/buildOperatorConstraint.ts","lineNumber":83,"sourceCode":"    resolvedOperator,\n    storage: 'column',\n    value: args.value,\n  }\n\n  for (const handler of matchingHandlers.filter(isTransformHandler)) {\n    let result: { column: Column | SQL; value: unknown }\n\n    try {\n      result = handler.transformOperands({ ...context })\n    } catch (error) {\n      throw new Error(\n        `Operator handler \"${handler.name}\" threw while transforming operands for the \"${resolvedOperator}\" operator at path \"${path}\".`,\n        { cause: error },\n      )\n    }\n\n    if (!result || typeof result !== 'object' || !('column' in result) || !('value' in result)) {\n      throw new APIError(\n        `Operator handler \"${handler.name}\" returned an invalid operand transform for the \"${resolvedOperator}\" operator at path \"${path}\". Expected an object with \"column\" and \"value\" properties.`,\n      )\n    }\n\n    context.column = result.column\n    context.value = result.value\n  }\n\n  const replacementHandler = matchingHandlers.find(isReplacementHandler)\n\n  if (replacementHandler) {\n    try {\n      return replacementHandler.build({ ...context })\n    } catch (error) {\n      throw new Error(\n        `Operator handler \"${replacementHandler.name}\" threw while building the \"${resolvedOperator}\" comparison at path \"${path}\".`,\n        { cause: error },\n      )","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/drizzle/src/queries/buildOperatorConstraint.ts#L65-L101","documentation":"`APIError` from `buildOperatorConstraint`: a `transformOperands` handler returned a value that is not a plain object with both `column` and `value` properties. The contract requires the handler to return `{ column: Column|SQL, value: unknown }` so the next handler / the final comparison can consume it; anything else (undefined, array, missing key) breaks the pipeline.","triggerScenarios":"A custom/built-in operand-transform handler returns `undefined`, returns an object missing `column` or `value`, returns a non-object, or forgets a `return` statement. Triggered when a query matches that handler's `operators`/`fieldTypes`.","commonSituations":"Handler author forgot `return` in an early-out branch; returned only `value` or only `column`; returned a raw SQL fragment instead of the wrapper object.","solutions":["Make the `transformOperands` implementation always return `{ column, value }` on every code path, including early returns.","Add a unit test asserting the handler's return shape for each operator/field type it matches.","If the transform shouldn't apply for some input, return `{ column, value }` unchanged rather than nothing."],"exampleFix":"// before\ntransformOperands: ({ column, value }) => {\n  if (value === null) return // returns undefined -> APIError\n  return { column: sql`lower(${column})`, value: String(value).toLowerCase() }\n}\n// after\ntransformOperands: ({ column, value }) => {\n  if (value === null) return { column, value }\n  return { column: sql`lower(${column})`, value: String(value).toLowerCase() }\n}","handlingStrategy":"validation","validationCode":"// Runtime check at handler registration\nfor (const h of operatorHandlers ?? []) {\n  if (typeof h.transformOperands === 'function') {\n    const out = h.transformOperands({ column: {} as any, value: 'x' } as any)\n    const ok = out && typeof out === 'object' && 'column' in out && 'value' in out\n    if (!ok) throw new Error(`Handler ${h.name} returned invalid transform shape`)\n  }\n}","typeGuard":"const isValidTransformResult = (r: unknown): r is { column: unknown; value: unknown } =>\n  typeof r === 'object' && r !== null && 'column' in r && 'value' in r","tryCatchPattern":"try {\n  await payload.find({ collection, where })\n} catch (err) {\n  if (/invalid operand transform/.test(String(err?.message))) {\n    payload.logger.error(`Fix the named handler to return { column, value } on every path.`)\n  }\n  throw err\n}","preventionTips":["Always return { column, value } from transformOperands, including early-out branches.","Add a unit test asserting the return shape for each matched operator/field type.","Use TypeScript return-type annotations to let the compiler enforce the shape."],"tags":["query","operator-handlers","contract-violation","custom-handler"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}