https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108859
Jonathan Wakely <redi at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Last reconfirmed|2023-02-20 00:00:00 |2025-5-29 --- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> --- #include <filesystem> #include <iostream> #include <stdlib.h> int main() { system("mkdir -p foo bar"); system("touch foo/file bar/file"); try { std::filesystem::copy(std::filesystem::path("foo"), std::filesystem::path("bar"), std::filesystem::copy_options::recursive); } catch (const std::filesystem::filesystem_error& e) { std::cerr << e.what() << '\n'; } } This prints: filesystem error: cannot copy: File exists [foo] [bar] But the problem is that bar/file exists, not that bar exists. This is because the throwing form of std::filesystem::copy just calls the non-throwing form: void fs::copy(const path& from, const path& to, copy_options options) { error_code ec; copy(from, to, options, ec); if (ec) _GLIBCXX_THROW_OR_ABORT(filesystem_error("cannot copy", from, to, ec)); } We would need to reimplement the throwing form to do all the work, and throw at the right places, or create a common implementation with an error context object which either stores an error_code or throws when an error is reported.