{"record":{"id":"7b921a1b0b5de955","repo":"Automattic/mongoose","slug":"value-cannot-be-casted-to-a-uuid","errorCode":null,"errorMessage":"\"${value}\" cannot be casted to a UUID","messagePattern":"\"(.+?)\" cannot be casted to a UUID","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/cast/uuid.js","lineNumber":32,"sourceCode":"  }\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":14,"sourceCodeEnd":36,"githubUrl":"https://github.com/Automattic/mongoose/blob/49cdab01366679723b487ecb754b38570f783289/lib/cast/uuid.js#L14-L36","documentation":"When the value for a UUID path is neither a string nor a BSON UUID, the caster falls back to toString() (skipping the default Object toString, per gh-647/gh-3030) and re-tests the result against UUID_FORMAT. If there is no usable toString or its output is not a canonical UUID, this final Error is thrown -- the type itself is unconvertible.","triggerScenarios":"doc.uid = new ObjectId('507f...') on a UUID path; doc.uid = 123; Buffer or custom-class instances whose toString() yields something other than a canonical UUID.","commonSituations":"Mixed ID regimes after migrations (ObjectId vs UUID); legacy numeric auto-increment IDs sent to UUID fields; wrapper ID classes; binary payloads passed raw instead of wrapped in bson's UUID.","solutions":["Convert explicitly to a canonical UUID string before assignment","If the values really are ObjectIds, declare the path Schema.Types.ObjectId instead of UUID","Wrap binary forms with new UUID(buffer) from the bson package"],"exampleFix":"// before\ndoc.uid = new ObjectId('507f1f77bcf86cd799439011'); // ObjectId -> UUID path\n\n// after\nconst schema = new Schema({ uid: Schema.Types.ObjectId }); // match the real ID type","handlingStrategy":"type-guard","validationCode":"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 normalizeUUIDInput(v) {\n  if (typeof v === 'string' || v == null) return v;\n  const s = typeof v.toString === 'function' ? v.toString() : null;\n  if (s == null || !UUID_RE.test(s)) {\n    throw new TypeError('Value is not convertible to a UUID');\n  }\n  return s;\n}\ndoc.uid = normalizeUUIDInput(input);","typeGuard":"function isUUIDCastable(v) {\n  if (typeof v === 'string') return true;\n  if (v == null || typeof v !== 'object') return false;\n  const s = typeof v.toString === 'function' ? v.toString() : null;\n  return s != null && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(s);\n}","tryCatchPattern":null,"preventionTips":["Keep one ID type per field across services; document it in the API contract","Parse and validate IDs at the edge, converting to canonical strings","Unit-test cross-type assignments (ObjectId -> UUID) to catch mix-ups"],"tags":["mongoose","uuid","cast","type-mismatch"],"backgroundTag":"invalid-uuid-format","analyzedSha":"49cdab01366679723b487ecb754b38570f783289","analyzedAt":"2026-08-21T22:54:00.882Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}