jquense/yup · error · TypeError

You cannot `concat()` schema's of different types: ${this.ty

Error message

You cannot `concat()` schema's of different types: ${this.type} and ${schema.type}

What it means

Schema.concat() merges two schemas, and merging schemas of different types (e.g. a string schema with a number schema) is meaningless. This TypeError is thrown unless both schemas share the same `type`, or the base schema is of type 'mixed' (which acts as a wildcard base).

Source

Thrown at src/schema.ts:284

    next.spec.meta = Object.assign(next.spec.meta || {}, args[0]);
    return next;
  }

  withMutation<T>(fn: (schema: this) => T): T {
    let before = this._mutate;
    this._mutate = true;
    let result = fn(this);
    this._mutate = before;
    return result;
  }

  concat(schema: this): this;
  concat(schema: AnySchema): AnySchema;
  concat(schema: AnySchema): AnySchema {
    if (!schema || schema === this) return this;

    if (schema.type !== this.type && this.type !== 'mixed')
      throw new TypeError(
        `You cannot \`concat()\` schema's of different types: ${this.type} and ${schema.type}`,
      );

    let base = this;
    let combined = schema.clone();

    const mergedSpec = { ...base.spec, ...combined.spec };

    combined.spec = mergedSpec;
    combined.internalTests = {
      ...base.internalTests,
      ...combined.internalTests,
    };

    // manually merge the blacklist/whitelist (the other `schema` takes
    // precedence in case of conflicts)
    combined._whitelist = base._whitelist.merge(
      schema._whitelist,

View on GitHub (pinned to ff31eee8a2)

Solutions

  1. Ensure both schemas come from the same top-level constructor (string with string, object with object)
  2. Wrap the base as yup.mixed() if you intentionally need to concat across types
  3. Fix the variable mixup so the intended schema is passed

Example fix

// before
const merged = yup.string().concat(yup.number());
// after
const merged = yup.string().concat(yup.string().max(10));
Defensive patterns

Strategy: type-guard

Validate before calling

function canConcat(a, b) { return !!b && (a.type === b.type || a.type === 'mixed'); }
const merged = canConcat(base, fragment) ? base.concat(fragment) : base.clone();

Type guard

function isSameType(a: yup.AnySchema, b: yup.AnySchema): boolean {
  return b != null && (a.type === b.type || a.type === 'mixed');
}

Try / catch

try { return base.concat(other); } catch (e) { if (/different types/.test(e.message)) return base.clone(); throw e; }

Prevention

When it happens

Trigger: Calling aStringSchema.concat(aNumberSchema), or concat-ing schemas built from different top-level builders like yup.string() vs yup.object(); also happens when a variable's schema type changed unexpectedly between versions of a shared base schema.

Common situations: Composing field schemas dynamically from config where the type of one schema was changed; accidentally passing the wrong schema variable; mixing object and array schemas when building reusable fragments.

Related errors


AI-assisted analysis of jquense/yup@ff31eee8a2 (2026-08-31). Data as JSON: /api/errors/295b53de8ec7ca43. Report an issue: GitHub.