{"record":{"id":"3ca4c37ee16c1066","repo":"facebook/react","slug":"copywithrename-expects-paths-to-be-the-same-exce","errorCode":null,"errorMessage":"copyWithRename() expects paths to be the same except for the deepest key","messagePattern":"copyWithRename\\(\\) expects paths to be the same except for the deepest key","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/react-reconciler/src/ReactFiberReconciler.js","lineNumber":671,"sourceCode":"        newPath,\n        index + 1,\n      );\n    }\n    return updated;\n  };\n\n  const copyWithRename = (\n    obj: Object | Array<any>,\n    oldPath: Array<string | number>,\n    newPath: Array<string | number>,\n  ): Object | Array<any> => {\n    if (oldPath.length !== newPath.length) {\n      console.warn('copyWithRename() expects paths of the same length');\n      return;\n    } else {\n      for (let i = 0; i < newPath.length - 1; i++) {\n        if (oldPath[i] !== newPath[i]) {\n          console.warn(\n            'copyWithRename() expects paths to be the same except for the deepest key',\n          );\n          return;\n        }\n      }\n    }\n    return copyWithRenameImpl(obj, oldPath, newPath, 0);\n  };\n\n  const copyWithSetImpl = (\n    obj: Object | Array<any>,\n    path: Array<string | number>,\n    index: number,\n    value: any,\n  ): $FlowFixMe => {\n    if (index >= path.length) {\n      return value;\n    }","sourceCodeStart":653,"sourceCodeEnd":689,"githubUrl":"https://github.com/facebook/react/blob/eafeac097ba51e1eab809c07102126bd5f8e5425/packages/react-reconciler/src/ReactFiberReconciler.js#L653-L689","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before: ancestor segment differs ('address' vs 'addr')\noverrideHookStateRenamePath(fiber, id, ['address', 'street'], ['addr', 'street']);\n\n// after: ancestors identical, deepest key renamed\noverrideHookStateRenamePath(fiber, id, ['address', 'street'], ['address', 'streetName']);","handlingStrategy":"type-guard","validationCode":"const ancestorsEqual = (a, b) =>\n  a.length === b.length &&\n  a.slice(0, -1).every((k, i) => k === b[i]);\n\nif (!ancestorsEqual(oldPath, newPath)) {\n  throw new Error('rename must keep every non-deepest segment identical');\n}\noverridePropsRenamePath(fiber, oldPath, newPath);","typeGuard":"function isValidRenamePath(oldPath, newPath) {\n  return (\n    Array.isArray(oldPath) &&\n    Array.isArray(newPath) &&\n    oldPath.length === newPath.length &&\n    oldPath.every((key, i) => i === oldPath.length - 1 || key === newPath[i])\n  );\n}","tryCatchPattern":null,"preventionTips":["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"],"tags":["devtools","path-validation","internal-api","state-editing","immutability"],"backgroundTag":"invalid-path-arguments","analyzedSha":"eafeac097ba51e1eab809c07102126bd5f8e5425","analyzedAt":"2026-08-21T22:01:08.818Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}