facebook/react · warning
copyWithRename() expects paths to be the same except for the
Error message
copyWithRename() expects paths to be the same except for the deepest key
What it means
Second validation in copyWithRename (ReactFiberReconciler.js:671): after lengths match, every path segment except the last must be identical, because the helper renames exactly one key in place. If any ancestor segment differs (['address','street'] vs ['addr','street']) it warns and returns undefined, and the DevTools caller then assigns undefined over hook state or pendingProps.
Source
Thrown at packages/react-reconciler/src/ReactFiberReconciler.js:671
newPath,
index + 1,
);
}
return updated;
};
const copyWithRename = (
obj: Object | Array<any>,
oldPath: Array<string | number>,
newPath: Array<string | number>,
): Object | Array<any> => {
if (oldPath.length !== newPath.length) {
console.warn('copyWithRename() expects paths of the same length');
return;
} else {
for (let i = 0; i < newPath.length - 1; i++) {
if (oldPath[i] !== newPath[i]) {
console.warn(
'copyWithRename() expects paths to be the same except for the deepest key',
);
return;
}
}
}
return copyWithRenameImpl(obj, oldPath, newPath, 0);
};
const copyWithSetImpl = (
obj: Object | Array<any>,
path: Array<string | number>,
index: number,
value: any,
): $FlowFixMe => {
if (index >= path.length) {
return value;
}View on GitHub (pinned to eafeac097b)
Solutions
- Keep all ancestor segments identical and change only the last: ['address','street'] to ['address','streetName']
- Recompute newPath from the same node as oldPath in the tool
- Use delete + set for cross-branch moves, which rename does not support
Example fix
// before: ancestor segment differs ('address' vs 'addr')
overrideHookStateRenamePath(fiber, id, ['address', 'street'], ['addr', 'street']);
// after: ancestors identical, deepest key renamed
overrideHookStateRenamePath(fiber, id, ['address', 'street'], ['address', 'streetName']); Defensive patterns
Strategy: type-guard
Validate before calling
const ancestorsEqual = (a, b) =>
a.length === b.length &&
a.slice(0, -1).every((k, i) => k === b[i]);
if (!ancestorsEqual(oldPath, newPath)) {
throw new Error('rename must keep every non-deepest segment identical');
}
overridePropsRenamePath(fiber, oldPath, newPath); Type guard
function isValidRenamePath(oldPath, newPath) {
return (
Array.isArray(oldPath) &&
Array.isArray(newPath) &&
oldPath.length === newPath.length &&
oldPath.every((key, i) => i === oldPath.length - 1 || key === newPath[i])
);
} Prevention
- Derive the new path by cloning the old path and replacing only the last segment
- Do not compute rename paths from two different tree snapshots
- Guard every rename call site - the internal helper returns undefined on bad input and clobbers state
When it happens
Trigger: Calling overrideHookStateRenamePath or overridePropsRenamePath with equal-length paths whose non-deepest segments differ, e.g. (['a','b','c'], ['x','b','c']). Emitted once per malformed call from DevTools-like tooling.
Common situations: Inspector code that renames a key in one subtree while the new name is computed from a sibling branch; copy-paste path constants; tree editors that let the user drag a key to a different parent while the rename API assumes the same parent.
Related errors
- copyWithRename() expects paths of the same length
- An unsupported type was passed to use(): ${String(usable)}
- Unknown Fiber. Needs to be a function component to inspect h
- Hooks not supported by this renderer
- getProfilingData not supported by this renderer
AI-assisted analysis of facebook/react@eafeac097b (2026-08-21).
Data as JSON: /api/errors/3ca4c37ee16c1066.
Report an issue: GitHub.