jquense/yup · error · Error
Yup.reach cannot implicitly index into a tuple type. the pat
Error message
Yup.reach cannot implicitly index into a tuple type. the path part "${lastPartDebug}" must contain an index to the tuple element, e.g. "${lastPartDebug}[0]" What it means
When reach()/getIn() traverses a path into a tuple schema, each path part must carry an explicit array index because tuples have heterogeneous, positional element types. This Error is thrown when a tuple is encountered but the current path part has no [index] bracket.
Source
Thrown at src/util/reach.ts:31
parent: any;
parentPath: string;
} {
let parent: any, lastPart: string, lastPartDebug: string;
// root path: ''
if (!path) return { parent, parentPath: path, schema };
forEach(path, (_part, isBracket, isArray) => {
let part = isBracket ? _part.slice(1, _part.length - 1) : _part;
schema = schema.resolve({ context, parent, value });
let isTuple = schema.type === 'tuple';
let idx = isArray ? parseInt(part, 10) : 0;
if (schema.innerType || isTuple) {
if (isTuple && !isArray)
throw new Error(
`Yup.reach cannot implicitly index into a tuple type. the path part "${lastPartDebug}" must contain an index to the tuple element, e.g. "${lastPartDebug}[0]"`,
);
if (value && idx >= value.length) {
throw new Error(
`Yup.reach cannot resolve an array item at index: ${_part}, in the path: ${path}. ` +
`because there is no value at that index. `,
);
}
parent = value;
value = value && value[idx];
schema = isTuple ? schema.spec.types[idx] : schema.innerType!;
}
// sometimes the array index part of a path doesn't exist: "nested.arr.child"
// in these cases the current part is the next schema and should be processed
// in this iteration. For cases where the index signature is included this
// check will fail and we'll handle the `child` part on the next iteration like normal
if (!isArray) {View on GitHub (pinned to ff31eee8a2)
Solutions
- Append an index to the path part: 'myTuple[0]'
- Change the schema field from tuple() back to array() if positional types aren't needed
- Use schema.at()/get on the tuple schema directly instead of reach
Example fix
// before yup.reach(schema, 'user.coords'); // after yup.reach(schema, 'user.coords[0]');
Defensive patterns
Strategy: validation
Validate before calling
function pathHasTupleIndex(path) {
return path.split('.').every(p => !p.startsWith('coords') || /\[\d+\]$/.test(p));
} Type guard
function hasTupleIndex(part: string): boolean {
return /\[\d+\]$/.test(part);
} Try / catch
try { return yup.reach(schema, path); } catch (e) { if (/implicitly index into a tuple/.test(e.message)) return yup.reach(schema, path + '[0]'); throw e; } Prevention
- Document tuple fields and require bracket-index syntax in path builders
- Use array() instead of tuple() when element types are uniform
- Unit-test reach() paths against the real schema
When it happens
Trigger: yup.reach(tupleSchema, 'myTuple') or 'nested.myTuple' where myTuple is a tuple — the part must be 'myTuple[0]' to select an element.
Common situations: Reusing plain-object paths against schemas converted to tuples; forgetting bracket syntax when tuple types were introduced in a schema refactor (yup.array() -> yup.tuple()).
Related errors
- Yup.reach cannot resolve an array item at index: ${_part}, i
- The schema does not contain the path: ${path}. (failed at: $
AI-assisted analysis of jquense/yup@ff31eee8a2 (2026-08-31).
Data as JSON: /api/errors/a181df2ac320c567.
Report an issue: GitHub.