{"record":{"id":"295b53de8ec7ca43","repo":"jquense/yup","slug":"you-cannot-concat-schema-s-of-different-types","errorCode":null,"errorMessage":"You cannot `concat()` schema's of different types: ${this.type} and ${schema.type}","messagePattern":"You cannot `concat\\(\\)` schema's of different types: (.+?) and (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/schema.ts","lineNumber":284,"sourceCode":"    next.spec.meta = Object.assign(next.spec.meta || {}, args[0]);\n    return next;\n  }\n\n  withMutation<T>(fn: (schema: this) => T): T {\n    let before = this._mutate;\n    this._mutate = true;\n    let result = fn(this);\n    this._mutate = before;\n    return result;\n  }\n\n  concat(schema: this): this;\n  concat(schema: AnySchema): AnySchema;\n  concat(schema: AnySchema): AnySchema {\n    if (!schema || schema === this) return this;\n\n    if (schema.type !== this.type && this.type !== 'mixed')\n      throw new TypeError(\n        `You cannot \\`concat()\\` schema's of different types: ${this.type} and ${schema.type}`,\n      );\n\n    let base = this;\n    let combined = schema.clone();\n\n    const mergedSpec = { ...base.spec, ...combined.spec };\n\n    combined.spec = mergedSpec;\n    combined.internalTests = {\n      ...base.internalTests,\n      ...combined.internalTests,\n    };\n\n    // manually merge the blacklist/whitelist (the other `schema` takes\n    // precedence in case of conflicts)\n    combined._whitelist = base._whitelist.merge(\n      schema._whitelist,","sourceCodeStart":266,"sourceCodeEnd":302,"githubUrl":"https://github.com/jquense/yup/blob/ff31eee8a2b10c938bb3a22544d9e33957a8cf01/src/schema.ts#L266-L302","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nconst merged = yup.string().concat(yup.number());\n// after\nconst merged = yup.string().concat(yup.string().max(10));","handlingStrategy":"type-guard","validationCode":"function canConcat(a, b) { return !!b && (a.type === b.type || a.type === 'mixed'); }\nconst merged = canConcat(base, fragment) ? base.concat(fragment) : base.clone();","typeGuard":"function isSameType(a: yup.AnySchema, b: yup.AnySchema): boolean {\n  return b != null && (a.type === b.type || a.type === 'mixed');\n}","tryCatchPattern":"try { return base.concat(other); } catch (e) { if (/different types/.test(e.message)) return base.clone(); throw e; }","preventionTips":["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"],"tags":["api-misuse","typeerror","schema-composition"],"backgroundTag":"incompatible-schema-merge","analyzedSha":"ff31eee8a2b10c938bb3a22544d9e33957a8cf01","analyzedAt":"2026-08-31T21:51:03.773Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}