Automattic/mongoose · error · CastError

Cast to UUID failed for value "${value}" (type ${valueType})

Error message

Cast to UUID failed for value "${value}" (type ${valueType}) at path "${path}"

What it means

CastError for `Schema.Types.UUID` paths. A value is cast by constructing a BSON UUID from it, so it must be a 32-char hex string, a 36-char hyphenated UUID string, a Buffer/Uint8Array(16), or an existing BSON UUID. Any other string (garbage, wrong length, braced '{...}'), number, or object throws this error.

Source

Thrown at lib/schema/uuid.js:207

SchemaUUID.prototype.cast = function(value, doc, init, prev, options) {
  if (utils.isNonBuiltinObject(value) &&
      SchemaType._isRef(this, value, doc, init)) {
    return this._castRef(value, doc, init, options);
  }

  let castFn;
  if (typeof this._castFunction === 'function') {
    castFn = this._castFunction;
  } else if (typeof this.constructor.cast === 'function') {
    castFn = this.constructor.cast();
  } else {
    castFn = SchemaUUID.cast();
  }

  try {
    return castFn(value);
  } catch (error) {
    throw new CastError(SchemaUUID.schemaName, value, this.path, error, this);
  }
};

/*!
 * ignore
 */

function handleSingle(val) {
  return this.cast(val);
}

/*!
 * ignore
 */

function handleArray(val) {
  return val.map((m) => {
    return this.cast(m);

View on GitHub (pinned to 49cdab0136)

Solutions

  1. Generate ids with `crypto.randomUUID()` / the `uuid` package, or wrap with `new mongoose.Types.UUID(value)`
  2. Validate the format before assigning: 32 or 36 lowercase-hex chars
  3. Fix stored values with an aggregation/update that normalizes to canonical form
  4. If the source sends binary, keep it as Buffer instead of a string

Example fix

// before
doc.uid = 'abc'; // throws

// after
doc.uid = crypto.randomUUID(); // e.g. '3f8a1c2e-9b4d-4e6a-8f2b-1c9d8e7f6a5b'
Defensive patterns

Strategy: validation

Validate before calling

const UUID_RE = /^(?:[0-9a-f]{24}|[0-9a-f]{32}|[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/i;
function assertUuidLike(v) {
  if (v == null || v instanceof Buffer || v instanceof Uint8Array) return;
  if (typeof v !== 'string' || !UUID_RE.test(v)) {
    throw new TypeError(`expected UUID string (32/36 hex chars), got: ${String(v)}`);
  }
}

Type guard

const isUuidString = v => typeof v === 'string' && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(v);

Try / catch

try {
  doc.uid = value;
} catch (err) {
  if (err instanceof mongoose.Error.CastError && err.kind === 'UUID') {
    // reject input; regenerate id with crypto.randomUUID() where appropriate
  } else throw err;
}

Prevention

When it happens

Trigger: `doc.uid = 'not-a-uuid'`; `doc.uid = 123`; a truncated copy-pasted UUID (35 chars); `'{' + id + '}'` braced formatting from another library.

Common situations: Hand-written seed/fixture files; generating ids without the uuid package; env/config truncation; mixing binary and string representations between services.

Related errors


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