{"record":{"id":"51a0bd28ff0cce3e","repo":"jquense/yup","slug":"array-of-sub-schema-must-be-a-valid-yup-schema","errorCode":null,"errorMessage":"`array.of()` sub-schema must be a valid yup schema not: ${printValue(schema)}","messagePattern":"`array\\.of\\(\\)` sub-schema must be a valid yup schema not: (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/array.ts","lineNumber":195,"sourceCode":"\n    if (schema.innerType)\n      // @ts-expect-error readonly\n      next.innerType = next.innerType\n        ? // @ts-expect-error Lazy doesn't have concat and will break\n          next.innerType.concat(schema.innerType)\n        : schema.innerType;\n\n    return next;\n  }\n\n  of<U>(\n    schema: ISchema<U, TContext>,\n  ): ArraySchema<U[] | Optionals<TIn>, TContext, TFlags> {\n    // FIXME: this should return a new instance of array without the default to be\n    let next = this.clone();\n\n    if (!isSchema(schema))\n      throw new TypeError(\n        '`array.of()` sub-schema must be a valid yup schema not: ' +\n          printValue(schema),\n      );\n\n    // @ts-expect-error readonly\n    next.innerType = schema;\n\n    next.spec = {\n      ...next.spec,\n      types: schema as ISchema<InnerType<TIn>, TContext>,\n    };\n\n    return next as any;\n  }\n\n  length(\n    length: number | Reference<number>,\n    message: Message<{ length: number }> = locale.length,","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/jquense/yup/blob/ff31eee8a2b10c938bb3a22544d9e33957a8cf01/src/array.ts#L177-L213","documentation":"ArraySchema.of() defines the schema for each array element and validates that the argument is a real yup schema using isSchema(). If not, it throws a TypeError that includes printValue(schema) so the developer can see what was actually passed. This catches passing plain constructors, strings like 'string', or wrong objects.","triggerScenarios":"yup.array().of('string'), yup.array().of(String), yup.array().of({ type: 'string' }), or of(x) where x is undefined due to a failed lookup / typo'd import (e.g. yup.stringg).","commonSituations":"Schema registries/factories that map string names to schemas returning undefined; migrating from other validator libs where element definitions are plain objects; dynamic schema builders hitting missing keys.","solutions":["Pass a yup schema instance: yup.array().of(yup.string().required()).","If building schemas from string names, verify the registry lookup returned a schema before calling of().","Fix typos in schema factory names and confirm imports resolve (undefined import)."],"exampleFix":"// before\nyup.array().of('string')\n// after\nyup.array().of(yup.string())","handlingStrategy":"type-guard","validationCode":"import { isSchema } from 'yup';\nconst arrayOf = (item) => {\n  if (!isSchema(item)) throw new TypeError(`array.of() needs a yup schema, got: ${JSON.stringify(item)}`);\n  return yup.array().of(item);\n};","typeGuard":"const isYupSchema = (v) => isSchema(v);","tryCatchPattern":null,"preventionTips":["Always construct element schemas via yup.* factories, never strings or native constructors.","Validate registry lookups before passing results to of().","Centralize array schema creation in one helper."],"tags":["yup","array","schema","type-error"],"backgroundTag":"invalid-subschema","analyzedSha":"ff31eee8a2b10c938bb3a22544d9e33957a8cf01","analyzedAt":"2026-08-31T21:51:03.773Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}