Solved here.
The fundamental issue is that if you don’t run a login manager, then when you log in, systemd will start the xdg-desktop-portal-gtk service which relies on having a display server running, but the display server will only run after calling sway post-login.
Therefore, xdg-desktop-portal-gtk (which picks the file chooser) will crash.
The bandaid solution is to place exec /usr/libexec/xdg-desktop-portal-gtk at the bottom of the sway config file, which will run the file chooser daemon upon starting the display server.
But ideally, either xdg-desktop-portal-gtk should never be called before the display server starts or run and handle the situation when no display server is running yet.