jquense/yup · error · TypeError
Must include `key` or `index` for nested validations
Error message
Must include `key` or `index` for nested validations
What it means
yup's asNestedTest builds the per-field test for validating an object property or array element. It requires either `key` (object field name) or `index` (array position) so it can read the nested value from the parent and build the correct path. If both are null, yup cannot address the nested value and throws this TypeError instead of producing a bogus path.
Source
Thrown at src/schema.ts:540
}
if (--count <= 0) {
nextOnce(nestedErrors);
}
});
}
}
asNestedTest({
key,
index,
parent,
parentPath,
originalParent,
options,
}: NestedTestConfig): RunTest {
const k = key ?? index;
if (k == null) {
throw TypeError('Must include `key` or `index` for nested validations');
}
const isIndex = typeof k === 'number';
let value = parent[k];
const testOptions = {
...options,
// Nested validations fields are always strict:
// 1. parent isn't strict so the casting will also have cast inner values
// 2. parent is strict in which case the nested values weren't cast either
strict: true,
parent,
value,
originalValue: originalParent[k],
// FIXME: tests depend on `index` being passed around deeply,
// we should not let the options.key/index bleed through
key: undefined,
// index: undefined,View on GitHub (pinned to ff31eee8a2)
Solutions
- Use the public API (object().shape({...}), array().of(...), validateAt(path, value)) so yup supplies key/index itself.
- If calling asNestedTest directly, pass either `key: 'fieldName'` or `index: 0` in the config object.
- Check custom integrations/plugins that build NestedTestConfig and ensure the field identifier is forwarded from the parent loop.
- After a yup upgrade, update internal-API usage to the current asNestedTest signature.
Example fix
// before
schema.asNestedTest({ parent: data, parentPath: 'user', originalParent: data, options });
// after
schema.asNestedTest({ key: 'user', parent: data, parentPath: 'user', originalParent: data, options }); Defensive patterns
Strategy: validation
Validate before calling
// if you must call asNestedTest, verify config first
function callNestedTest(schema, cfg) {
if (cfg.key == null && cfg.index == null) {
throw new TypeError('asNestedTest requires key or index');
}
return schema.asNestedTest(cfg);
} Type guard
function hasNestedKey(cfg: { key?: string | number; index?: number }): boolean {
return cfg.key != null || cfg.index != null;
} Try / catch
try {
const test = schema.asNestedTest({ key, index, parent, parentPath, originalParent, options });
test({ value: parent[key], options }, panic, next);
} catch (e) {
if (e instanceof TypeError && /key.*index/.test(e.message)) {
console.error('NestedTestConfig missing key/index:', cfg);
}
} Prevention
- Prefer public APIs (shape, of, validateAt) over internals so key/index are derived automatically.
- When composing schemas in custom bindings, always forward the loop's key or index into NestedTestConfig.
- Recheck internal-API calls after every yup major upgrade.
- Write a smoke test that validates a nested object and array path to catch missing identifiers early.
When it happens
Trigger: Calling low-level schema internals (e.g. schema.asNestedTest({...}) or casting/validating through internals like cast with nested schemas) without passing key/index; usually via misuse of internal APIs or a plugin/binding that composes nested schemas incorrectly rather than through normal object().shape()/array().of() usage.
Common situations: Custom form-library bindings (e.g. hand-rolled Formik alternatives) wiring yup internals; calling validateAt/cast on nested schemas with hand-built options objects; after upgrading yup where the internal NestedTestConfig contract changed.
Understand the failure class
Background: "Must pass :limit option" / "Missing required option" — required option errors explained — this error's family across 41 libraries.
Related errors
- either `then:` or `otherwise:` is required for `when()` cond
- conditions must return a schema object
- lazy() functions must return a valid schema
- ref must be a string, got:
- ref must be a non-empty string
AI-assisted analysis of jquense/yup@ff31eee8a2 (2026-08-31).
Data as JSON: /api/errors/468f7ecace051294.
Report an issue: GitHub.