{"record":{"id":"e025602e51b747da","repo":"hcengineering/platform","slug":"nin-predicate-requires-array","errorCode":null,"errorMessage":"$nin predicate requires array","messagePattern":"\\$nin predicate requires array","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"foundations/core/packages/core/src/predicate.ts","lineNumber":68,"sourceCode":"          return o.some((p) => p == value)\n        }\n      })\n  },\n  $all: (o, propertyKey) => {\n    if (!Array.isArray(o)) {\n      throw new Error('$all predicate requires array')\n    }\n    return (docs) =>\n      execPredicate(docs, propertyKey, (value: any[]) => {\n        for (const val of o) {\n          if (!value.includes(val)) return false\n        }\n        return true\n      })\n  },\n  $nin: (o, propertyKey) => {\n    if (!Array.isArray(o)) {\n      throw new Error('$nin predicate requires array')\n    }\n    return (docs) =>\n      execPredicate(docs, propertyKey, (value) => {\n        if (Array.isArray(value)) {\n          return !o.some((p) => value.includes(p))\n        } else {\n          // eslint-disable-next-line eqeqeq\n          return !o.some((p) => p == value)\n        }\n      })\n  },\n\n  $like: (query: string, propertyKey: string): Predicate => {\n    const searchString = query\n      .split('%')\n      .map((it) => escapeLikeForRegexp(it))\n      .join('.*')\n    const regex = RegExp(`^${searchString}$`, 'i')","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/foundations/core/packages/core/src/predicate.ts#L50-L86","documentation":"The $nin (not-in) predicate excludes documents whose property matches any element of a supplied list, so the argument must be an array. predicate.ts throws this error during predicate construction when the value after $nin is not an Array. Like $in and $all, this mirrors MongoDB's required array argument.","triggerScenarios":"Queries like { status: { $nin: 'archived' } } (bare string) or { _id: { $nin: excludedIds } } where excludedIds is undefined/null/a single id object rather than an array.","commonSituations":"A single excluded value not wrapped in an array; ids arriving from URL params or config as a comma string; an upstream variable that is null because the exclusion list failed to load.","solutions":["Wrap the value(s) in an array: { $nin: ['archived'] }.","Normalize dynamic input with Array.isArray and fall back to [] when absent.","Split comma-separated strings before passing: str.split(',')."],"exampleFix":"// before\nconst q = { _class: { $nin: excluded } }\n// after\nconst q = { _class: { $nin: Array.isArray(excluded) ? excluded : excluded != null ? [excluded] : [] } }","handlingStrategy":"validation","validationCode":"const nin = Array.isArray(excluded) ? excluded : excluded != null ? [excluded] : []\nconst q = { _class: { $nin: nin } }","typeGuard":"function isExclusionList(v: unknown): v is unknown[] {\n  return v == null || Array.isArray(v)\n}","tryCatchPattern":"try {\n  return await find(clazz, query)\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('$nin predicate requires array')) {\n    return await find(clazz, { ...query, _class: { $nin: [] } })\n  }\n  throw e\n}","preventionTips":["Split comma-separated string inputs into arrays before querying.","Wrap single excluded values in arrays at the query-builder layer.","Guard against null exclusion lists loaded from remote config."],"tags":["query","predicate","type-error"],"backgroundTag":"predicate-requires-array","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}