{"record":{"id":"312d69883542ef6c","repo":"Automattic/mongoose","slug":"value-is-not-a-valid-uuid-string","errorCode":null,"errorMessage":"\"${value}\" is not a valid UUID string","messagePattern":"\"(.+?)\" is not a valid UUID string","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/cast/uuid.js","lineNumber":19,"sourceCode":"'use strict';\n\nconst UUID = require('mongodb/lib/bson').UUID;\n\nconst UUID_FORMAT = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/i;\n\nmodule.exports = function castUUID(value) {\n  if (value == null) {\n    return value;\n  }\n\n  if (value instanceof UUID) {\n    return value;\n  }\n  if (typeof value === 'string') {\n    if (UUID_FORMAT.test(value)) {\n      return new UUID(value);\n    } else {\n      throw new Error(`\"${value}\" is not a valid UUID string`);\n    }\n  }\n\n  // Re: gh-647 and gh-3030, we're ok with casting using `toString()`\n  // **unless** its the default Object.toString, because \"[object Object]\"\n  // doesn't really qualify as useful data\n  if (value.toString && value.toString !== Object.prototype.toString) {\n    if (UUID_FORMAT.test(value.toString())) {\n      return new UUID(value.toString());\n    }\n  }\n\n  throw new Error(`\"${value}\" cannot be casted to a UUID`);\n};\n\nmodule.exports.UUID_FORMAT = UUID_FORMAT;\n","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/Automattic/mongoose/blob/49cdab01366679723b487ecb754b38570f783289/lib/cast/uuid.js#L1-L36","documentation":"A Schema.Types.UUID path accepts strings matching mongoose's UUID_FORMAT -- the canonical 8-4-4-4-12 hexadecimal form -- and wraps them in BSON's UUID. Any other string shape (wrong grouping, missing hyphens, braces, non-hex characters) throws this Error with the value quoted in the message.","triggerScenarios":"doc.uid = 'not-a-uuid'; '123e4567e89b12d3a456426614174000' (no hyphens); '{123e4567-e89b-12d3-a456-426614174000}' (braces); values pasted with whitespace; user-supplied IDs taken from URLs.","commonSituations":"Custom ID generators; third-party IDs that are ULIDs, ObjectIds, or base64 strings sent to UUID fields; manual re-formatting that drops hyphens; format drift between producer and consumer.","solutions":["Normalize before assignment: trim, strip braces and 'urn:uuid:' prefixes, re-insert hyphens if you store compact form","Generate IDs with crypto.randomUUID() or new UUID() from bson so the format is guaranteed","Validate with the same pattern up front and reject early"],"exampleFix":"// before\ndoc.uid = '123e4567e89b12d3a456426614174000'; // missing hyphens\n\n// after\ndoc.uid = '123e4567-e89b-12d3-a456-426614174000';","handlingStrategy":"validation","validationCode":"const { UUID_FORMAT } = require('mongoose/lib/cast/uuid');\nfunction isValidUUIDString(v) {\n  return typeof v === 'string' && UUID_FORMAT.test(v);\n}\nif (!isValidUUIDString(req.params.id)) {\n  return res.status(400).json({ error: 'invalid uuid' });\n}","typeGuard":"const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nfunction isUUID(v) {\n  return typeof v === 'string' && UUID_RE.test(v);\n}","tryCatchPattern":"try {\n  await Model.findById(req.params.id);\n} catch (err) {\n  if (err.message.includes('is not a valid UUID string')) {\n    // treat as 404/400: the id cannot exist in canonical form\n  }\n  throw err;\n}","preventionTips":["Validate id route params with a UUID regex before querying","Prefer crypto.randomUUID() for generation","Keep one canonical formatting helper instead of ad-hoc string surgery"],"tags":["mongoose","uuid","cast","format-validation"],"backgroundTag":"invalid-uuid-format","analyzedSha":"49cdab01366679723b487ecb754b38570f783289","analyzedAt":"2026-08-21T22:54:00.882Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}