{"record":{"id":"a55bce12a7420093","repo":"gatsbyjs/gatsby","slug":"bad-filter-value-for-predicate-filter-comparator","errorCode":null,"errorMessage":"Bad filter value for predicate ${filter.comparator}: ${inspect(filter.value)}","messagePattern":"Bad filter value for predicate (.+?): (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/gatsby/src/datastore/lmdb/query/filter-using-index.ts","lineNumber":689,"sourceCode":" *\n * This method relies on ordered-binary format used by lmdb-store to persist keys\n * and assumes keys are composite and represented as arrays.\n *\n * Implementation detail: ordered-binary treats `null` as multipart separator within binary sequence\n */\nfunction getValueEdgeAfter(value: IndexFieldValue): RangeEdgeAfter {\n  return [value, BinaryInfinityPositive]\n}\nfunction getValueEdgeBefore(value: IndexFieldValue): RangeEdgeBefore {\n  return [undefinedSymbol, value]\n}\n\nfunction toIndexFieldValue(\n  filterValue: DbComparatorValue,\n  filter: IDbFilterStatement\n): IndexFieldValue {\n  if (typeof filterValue === `object` && filterValue !== null) {\n    throw new Error(\n      `Bad filter value for predicate ${filter.comparator}: ${inspect(\n        filter.value\n      )}`\n    )\n  }\n  return filterValue\n}\n\nfunction getIdentifier(entry: IIndexEntry): number | string {\n  const id = entry.key[entry.key.length - 1]\n  if (typeof id !== `number` && typeof id !== `string`) {\n    const out = inspect(id)\n    throw new Error(\n      `Last element of index key is expected to be numeric or string id, got ${out}`\n    )\n  }\n  return id\n}","sourceCodeStart":671,"sourceCodeEnd":707,"githubUrl":"https://github.com/gatsbyjs/gatsby/blob/8b06340921ffdf23125a365b9c9923690cb62ce6/packages/gatsby/src/datastore/lmdb/query/filter-using-index.ts#L671-L707","documentation":"`toIndexFieldValue` converts a comparator value to an LMDB key. A non-null object is invalid for any single-value comparator, so the planner rejects it and prints the offending value via `inspect` along with the comparator name.","triggerScenarios":"Any indexed comparator receiving an object value, e.g. `{ eq: { foo: 1 } }` on an indexed scalar field.","commonSituations":"Generic/programmatic query builders passing through nested objects; source/transform producing object values on indexed fields.","solutions":["Provide a primitive (or for `in`/`nin`, an array of primitives) to the comparator.","If you need object equality, index a derived scalar key instead."],"exampleFix":"// before\nfilter: { code: { eq: { value: \"A1\" } } }\n// after\nfilter: { code: { eq: \"A1\" } }","handlingStrategy":"validation","validationCode":"function assertScalarComparator(op, value) {\n  if (typeof value === \"object\" && value !== null && !Array.isArray(value)) {\n  throw new Error(`${op} value must be primitive, got object`)\n  }\n}\n","typeGuard":"function isComparatorPrimitive(v: unknown): v is string | number | boolean | null {\n  return v === null || [\"string\", \"number\", \"boolean\"].includes(typeof v)\n}\n","tryCatchPattern":null,"preventionTips":["Type comparator values strictly; disallow generic objects.","Derive scalar keys for equality/range filters instead of indexing objects."],"tags":["graphql","query","filter","lmdb","indexing","datastore"],"backgroundTag":null,"analyzedSha":"8b06340921ffdf23125a365b9c9923690cb62ce6","analyzedAt":"2026-08-13T02:36:21.405Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}