Title: fsPromises.cp(...) inconsistencies and bugs · Issue #58869 · nodejs/node · GitHub
Open Graph Title: fsPromises.cp(...) inconsistencies and bugs · Issue #58869 · nodejs/node
X Title: fsPromises.cp(...) inconsistencies and bugs · Issue #58869 · nodejs/node
Description: The fsPromises.cp and fs.cp methods are inconsistent with the sync version because they do not correctly accept Buffer file paths. This also means it also improperly handles non-UTF8 encoded filenames. The sync variation supports Buffer....
Open Graph Description: The fsPromises.cp and fs.cp methods are inconsistent with the sync version because they do not correctly accept Buffer file paths. This also means it also improperly handles non-UTF8 encoded filena...
X Description: The fsPromises.cp and fs.cp methods are inconsistent with the sync version because they do not correctly accept Buffer file paths. This also means it also improperly handles non-UTF8 encoded filena...
Opengraph URL: https://github.com/nodejs/node/issues/58869
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"fsPromises.cp(...) inconsistencies and bugs","articleBody":"The fsPromises.cp and fs.cp methods are inconsistent with the sync version because they do not correctly accept Buffer file paths. This also means it also improperly handles non-UTF8 encoded filenames. The sync variation supports Buffer.\n\nThe method also does not appropriately validate inputs. Rather than throwing a proper Node.js type error when a Buffer is passed, it tries to use it and fails at another point deeper in the function. \n\nThe impl of the async version of the method is also needlessly structured differently from the sync version leading to a fair amount of duplicated and inconsistent code, making it difficult to fix the inconsistencies. The sync version was updated recently to move significant pieces to C++ while the async versions were not similarly updated.\n\nExample:\n\n```js\nfs.cpSync(Buffer.from('a'), Buffer.from('b')); // works!\n\nfs.cp(Buffer.from('a'), Buffer.from('b'), (err) =\u003e { /* ... */ }); // fails!\n```\n\nThe error thrown is:\n\n```\nTypeError [ERR_INVALID_ARG_TYPE]: The \"paths[0]\" argument must be of type string. Received an instance of Buffer\n at resolve (node:path:1195:7)\n at normalizePathToArray (node:internal/fs/cp/cp:185:45)\n at isSrcSubdir (node:internal/fs/cp/cp:190:18)\n at checkPaths (node:internal/fs/cp/cp:110:32)\n at async cpFn (node:internal/fs/cp/cp:66:17)\n```\n\n`fs.cp(...)` is currently just a `callbackified(...)` version of `fsPromise.cp(...)`, so fixing one should fix the other:\n\nThere are several fixes necessary: If `Buffer` is not going to be accepted, then the method should properly validate that the input `src` and `dest` are not Buffers and throw a proper `ERR_INVALID_ARG_TYPE` error. However, not accepting `Buffer` mean that the async versions of these will not properly handle non-UTF8 encoded file names. Ideally, the method would be updated to accept `Buffer` paths, but that means the `normalizePathToArray` method needs to be updated/refactored.\n\nSecond, the differences that were introduced when the sync version was updated to move chunks to C++ make it rather difficult to keep these methods in sync with each other. There is a strong possibility/likelihood of inadvertently introducing behavioral differences between the two that increase the likelihood of more inconsistencies being introduced in the future. We should probably move the entire implementation of the cp callback, cp promise, and cp sync methods into C++ if we're going to have any of the implementation in C++, having those eliminate duplicated logic as much as possible.\n\nThere is another bug in the implementation of these methods with regards to the `options.filter` option, which does not correctly handle the case in cpSync when the `src` and `dest` are passed as `Buffer` and when the children of copied directories are not UTF8 encoded file names. The differences in the implementation of the sync and async versions of the cp function make it quite difficult to introduce a consistent fix across the variations. The implementations should be reconciled and moved to C++ first, *including* the case where `options.filter` is called, before we can properly fix the `options.filter` implementation in a consistent way.\n\n@nodejs/fs @dario-piotrowicz @anonrig ","author":{"url":"https://github.com/jasnell","@type":"Person","name":"jasnell"},"datePublished":"2025-06-27T20:04:32.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":3},"url":"https://github.com/58869/node/issues/58869"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:43bdf35b-a862-ba83-3d9d-545e4b6bd8d3 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | E3D0:34DA5A:C06A1E:105FA11:6A4ED990 |
| html-safe-nonce | b1f734aeaf390c44a86181c850b97f165eab8791f285b9af3aaffb7e49e34cb7 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJFM0QwOjM0REE1QTpDMDZBMUU6MTA1RkExMTo2QTRFRDk5MCIsInZpc2l0b3JfaWQiOiIyNjYxNzE5Nzg3NzgwODg4OTc2IiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0= |
| visitor-hmac | c2f690fef32e6e98d18e5bea390228c7df73fe2dae6ea5ea2d19109f3a68b697 |
| hovercard-subject-tag | issue:3183975432 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/nodejs/node/58869/issue_layout |
| twitter:image | https://opengraph.githubassets.com/dfcf9daf346d667961a3ea2802034177e6f4ff79c666c2dbc9f00dd20da6fe31/nodejs/node/issues/58869 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/dfcf9daf346d667961a3ea2802034177e6f4ff79c666c2dbc9f00dd20da6fe31/nodejs/node/issues/58869 |
| og:image:alt | The fsPromises.cp and fs.cp methods are inconsistent with the sync version because they do not correctly accept Buffer file paths. This also means it also improperly handles non-UTF8 encoded filena... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | jasnell |
| hostname | github.com |
| expected-hostname | github.com |
| None | 41b6ab3ba6d20a71766ac245b5a4a94c6fc672a9cd4da7d44c1b33ab8bf6a21c |
| turbo-cache-control | no-preview |
| go-import | github.com/nodejs/node git https://github.com/nodejs/node.git |
| octolytics-dimension-user_id | 9950313 |
| octolytics-dimension-user_login | nodejs |
| octolytics-dimension-repository_id | 27193779 |
| octolytics-dimension-repository_nwo | nodejs/node |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 27193779 |
| octolytics-dimension-repository_network_root_nwo | nodejs/node |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | c37fe3e3f5f306900bd5b6bee97463f66c938b2c |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width