{"record":{"id":"33f38e3c8886a4b0","repo":"redis/node-redis","slug":"version-is-not-a-valid-redis-version","errorCode":null,"errorMessage":"${version} is not a valid redis version","messagePattern":"(.+?) is not a valid redis version","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/test-utils/lib/index.ts","lineNumber":222,"sourceCode":"> {\n  client: ClientTestOptions<M, F, S, RESP, TYPE_MAPPING>;\n  cluster: ClusterTestOptions<M, F, S, RESP, TYPE_MAPPING/*, POLICIES*/>;\n}\n\ninterface Version {\n  tag: string;\n  numbers: Array<number>;\n}\n\nexport default class TestUtils {\n  static parseVersionNumber(version: string): Array<number> {\n    if (version === 'latest' || version === 'edge') return [Infinity];\n\n\n    // Match complete version number patterns\n    const versionMatch = version.match(/(^|-)\\d+(\\.\\d+)*($|-)/);\n    if (!versionMatch) {\n      throw new TypeError(`${version} is not a valid redis version`);\n    }\n\n    // Extract just the numbers and dots between first and last dash (or start/end)\n    const versionNumbers = versionMatch[0].replace(/^-|-$/g, '');\n\n    return versionNumbers.split('.').map(x => {\n      const value = Number(x);\n      if (Number.isNaN(value)) {\n        throw new TypeError(`${version} is not a valid redis version`);\n      }\n      return value;\n    });\n  }\n  static #getVersion(\n    tagArgumentName: string,\n    versionArgumentName: string | undefined,\n    defaultVersion: string | { tag: string; version: string } = 'latest'\n  ): Version {","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/redis/node-redis/blob/90fd0652bc3f2a0a1b2f79fa9096b02a86b0ac58/packages/test-utils/lib/index.ts#L204-L240","documentation":"TestUtils.parseVersionNumber throws a TypeError when the version string contains no substring matching the regex (^|-)\\d+(\\.\\d+)*($|-) — i.e., there is no digit run delimited by string start, end, or a dash. The method parses the Redis docker image tag or an explicit --redis-version into comparable numeric components; 'latest' and 'edge' are special-cased to [Infinity] before this check.","triggerScenarios":"Passing a tag or version string with no bounded numeric run: e.g. 'alpine', 'nightly', 'rc', or any purely alphabetic label. Reached via #getVersion from --docker-image-arg/--redis-version CLI args or the defaultVersion option when the resolved versionToParse is non-numeric.","commonSituations":"CI overrides the image tag with a word label (not 'latest'/'edge'); a typo in --redis-version; a custom defaultVersion object whose version field is a non-numeric label; using an image tag scheme the parser doesn't anticipate.","solutions":["Pass a version containing a numeric run such as '7.4', '7.2.4', or '7.4-rc2' (the regex matches the 7.4 portion).","Use the special tokens 'latest' or 'edge', which short-circuit to [Infinity] before the regex runs.","Keep a non-numeric tag but supply --redis-version explicitly with a numeric value; #getVersion prioritizes the explicit version over the tag.","If you need a non-numeric tag with no numeric component, extend the special-case list or adjust the regex rather than fighting the parser."],"exampleFix":"// before — non-numeric tag, regex finds no digit run\n TestUtils.parseVersionNumber('alpine') // throws\n\n// after — supply a numeric version, or use a tag containing digits\n TestUtils.parseVersionNumber('7.4-alpine') // -> [7, 4]\n // or keep the tag and pass --redis-version=7.4.0 on the CLI","handlingStrategy":"validation","validationCode":"const VERSION_LIKE = /(^|-)\\d+(\\.\\d+)*($|-)/;\nfunction isParsableVersion(v: string): boolean {\n  return v === 'latest' || v === 'edge' || VERSION_LIKE.test(v);\n}\n// before calling TestUtils.parseVersionNumber(tag):\nif (!isParsableVersion(tag)) throw new Error(`Tag '${tag}' has no numeric version; pass --redis-version=N.N`);","typeGuard":"const isVersionString = (v: unknown): v is string =>\n  typeof v === 'string' && (v === 'latest' || v === 'edge' || /(^|-)\\d+(\\.\\d+)*($|-)/.test(v));","tryCatchPattern":"try {\n  TestUtils.parseVersionNumber(maybeTag);\n} catch (e) {\n  if (e instanceof TypeError) {\n    // fall back to an explicit numeric version, or fail fast with actionable guidance\n    throw new Error(`Unparseable image tag '${maybeTag}'; set --redis-version=N.N.N`);\n  }\n  throw e;\n}","preventionTips":["Prefer numeric image tags (7.4, 7.2.4) or the special 'latest'/'edge' tokens.","When using a non-numeric tag, always pass --redis-version explicitly so #getVersion does not fall back to parsing the tag.","Validate user-supplied tags with the regex above before they reach the test harness."],"tags":["test-utils","version","configuration","typescript"],"backgroundTag":null,"analyzedSha":"90fd0652bc3f2a0a1b2f79fa9096b02a86b0ac58","analyzedAt":"2026-08-11T15:37:21.243Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}