{"record":{"id":"356a4903a58d857b","repo":"redis/node-redis","slug":"the-digest-function-requires-the-node-rs-xxhas","errorCode":null,"errorMessage":"The \"digest\" function requires the \"@node-rs/xxhash\" package, but it was not found.","messagePattern":"The \"digest\" function requires the \"@node-rs/xxhash\" package, but it was not found\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/client/lib/utils/digest.ts","lineNumber":13,"sourceCode":"import { RedisArgument } from '../RESP/types';\n\ntype Xxh3Module = typeof import('@node-rs/xxhash').xxh3;\n\nlet xxh3Cache: Xxh3Module | null = null;\n\nasync function getXxh3(): Promise<Xxh3Module> {\n  if (!xxh3Cache) {\n    try {\n      const module = await import('@node-rs/xxhash');\n      xxh3Cache = module.xxh3;\n    } catch {\n      throw new Error(\n        'The \"digest\" function requires the \"@node-rs/xxhash\" package, but it was not found.'\n      );\n    }\n  }\n  return xxh3Cache;\n}\n\n/**\n * Computes a deterministic 64-bit XXH3 digest of the input.\n *\n * This produces the same digest that Redis computes internally via the `DIGEST` command,\n * allowing you to use it with conditional SET and DELEX operations (`IFDEQ`, `IFDNE`).\n *\n * @param value - The value to compute the digest for (string or Buffer)\n * @returns A 16-character lowercase hexadecimal digest\n * @throws If the `@node-rs/xxhash` package is not found\n */\nexport async function digest(value: RedisArgument): Promise<string> {","sourceCodeStart":1,"sourceCodeEnd":31,"githubUrl":"https://github.com/redis/node-redis/blob/90fd0652bc3f2a0a1b2f79fa9096b02a86b0ac58/packages/client/lib/utils/digest.ts#L1-L31","documentation":"The `digest()` helper computes a deterministic 64-bit XXH3 hash matching Redis's internal DIGEST, used for conditional SET/DELEX operations (`IFDEQ`, `IFDNE`). It lazy-imports `@node-rs/xxhash`, which is an optional peer dependency; if the package cannot be imported, getXxh3() throws this error. The cache means the import is attempted at most once per process.","triggerScenarios":"Calling `digest(value)` (directly or via IFDEQ/IFDNE command construction) in a project that has not installed `@node-rs/xxhash`. The dynamic import fails and the error is thrown.","commonSituations":"Using conditional-value commands without adding the optional native dependency; bundler/monorepo that strips optional deps; native binary missing for the platform; npm install with `--omit=optional`.","solutions":["Install the package: `npm install @node-rs/xxhash`.","Ensure optional dependencies are not filtered out in install/CI.","Use the matching platform binary (prebuilt) for your runtime."],"exampleFix":"// before\ndigest(value) // throws: package missing\n// after (terminal)\nnpm install @node-rs/xxhash\n// then in code\ndigest(value)","handlingStrategy":"validation","validationCode":"async function xxhashAvailable(): Promise<boolean> {\n  try { await import('@node-rs/xxhash'); return true; } catch { return false; }\n}\nif (!await xxhashAvailable()) {\n  throw new Error('Run: npm install @node-rs/xxhash');\n}","typeGuard":null,"tryCatchPattern":"let digestFn: ((v: string | Buffer) => Promise<string>) | undefined;\ntry { digestFn = (await import(/* @vite-ignore */ 'packages/client/lib/utils/digest')).digest; }\ncatch (e) {\n  if (String(e).includes('@node-rs/xxhash')) {\n    console.error('Install optional dep: npm i @node-rs/xxhash');\n  }\n  throw e;\n}","preventionTips":["Add @node-rs/xxhash to dependencies when using IFDEQ/IFDNE.","Do not strip optional dependencies in production installs."],"tags":["digest","optional-dependency","native-module","conditional-commands"],"backgroundTag":null,"analyzedSha":"90fd0652bc3f2a0a1b2f79fa9096b02a86b0ac58","analyzedAt":"2026-08-11T15:37:21.243Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}