Automattic/mongoose · error · Error

"${value}" cannot be casted to a UUID

Error message

"${value}" cannot be casted to a UUID

What it means

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.

Source

Thrown at lib/cast/uuid.js:32

  }
  if (typeof value === 'string') {
    if (UUID_FORMAT.test(value)) {
      return new UUID(value);
    } else {
      throw new Error(`"${value}" is not a valid UUID string`);
    }
  }

  // Re: gh-647 and gh-3030, we're ok with casting using `toString()`
  // **unless** its the default Object.toString, because "[object Object]"
  // doesn't really qualify as useful data
  if (value.toString && value.toString !== Object.prototype.toString) {
    if (UUID_FORMAT.test(value.toString())) {
      return new UUID(value.toString());
    }
  }

  throw new Error(`"${value}" cannot be casted to a UUID`);
};

module.exports.UUID_FORMAT = UUID_FORMAT;

View on GitHub (pinned to 49cdab0136)

Solutions

  1. Convert explicitly to a canonical UUID string before assignment
  2. If the values really are ObjectIds, declare the path Schema.Types.ObjectId instead of UUID
  3. Wrap binary forms with new UUID(buffer) from the bson package

Example fix

// before
doc.uid = new ObjectId('507f1f77bcf86cd799439011'); // ObjectId -> UUID path

// after
const schema = new Schema({ uid: Schema.Types.ObjectId }); // match the real ID type
Defensive patterns

Strategy: type-guard

Validate before calling

const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
function normalizeUUIDInput(v) {
  if (typeof v === 'string' || v == null) return v;
  const s = typeof v.toString === 'function' ? v.toString() : null;
  if (s == null || !UUID_RE.test(s)) {
    throw new TypeError('Value is not convertible to a UUID');
  }
  return s;
}
doc.uid = normalizeUUIDInput(input);

Type guard

function isUUIDCastable(v) {
  if (typeof v === 'string') return true;
  if (v == null || typeof v !== 'object') return false;
  const s = typeof v.toString === 'function' ? v.toString() : null;
  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);
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of Automattic/mongoose@49cdab0136 (2026-08-21). Data as JSON: /api/errors/7b921a1b0b5de955. Report an issue: GitHub.