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
- Ensure both schemas come from the same top-level constructor (string with string, object with object)
- Wrap the base as yup.mixed() if you intentionally need to concat across types
- 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
- Keep schema fragments grouped by their base type
- Type concat arguments with generics so TS enforces matching types
- Log schema.type during dynamic schema composition debugging
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
- Only valid options for round() are: ${avail.join(', ')}
- `test` is a required parameters
- Exclusive tests must provide a unique `name` identifying the
- The value of ${options.path || 'field'} could not be cast to
- Must include `key` or `index` for nested validations
AI-assisted analysis of jquense/yup@ff31eee8a2 (2026-08-31).
Data as JSON: /api/errors/295b53de8ec7ca43.
Report an issue: GitHub.