Your Expo app builds fine in the cloud. On Windows, gradlew bundleRelease gets well into the native part of the build and then stops in a task like this:
> Task :app:buildCMakeRelWithDebInfo[arm64-v8a] FAILED
...
Stat(C:/Users/<you>/Documents/Projects/<your-app>/android/app/.cxx/RelWithDebInfo/<hash>/arm64-v8a/...): Filename longer than 260 characters
The last line is the message ninja itself prints, taken from its source code. We didn't keep the raw log of our failure, so the Gradle output around it is abbreviated and the path is an example.
Nothing is wrong with your code. The project simply lives too deep on the disk. This article explains why it happens and how to fix it by hand, then what WinBuild does about it.
Why it happens
Windows' classic path limit, MAX_PATH, is 260 characters. React Native's native build goes deep. Gradle runs CMake for each ABI, CMake generates a build.ninja file under android/app/.cxx/RelWithDebInfo/<hash>/<abi>/, and the build pulls in prefab packages (native headers and libraries of React Native and your native modules) with long paths of their own. Add a project folder like C:\Users\<you>\Documents\Projects\<your-app> and a single header path can easily go past 260.
The process that gives up is ninja. On Windows, before it reads a file, ninja checks the path length and returns exactly this error when the path is longer than MAX_PATH:
Stat(<path>): Filename longer than 260 characters
"Can't I just enable long paths?"
That's the first answer you'll find, and here it usually isn't enough. Windows long-path support needs two things: the LongPathsEnabled registry value (admin rights, sometimes a reboot), and a program that declares itself longPathAware in its manifest. Only ninja 1.12.0 (April 2024) and later declare it and skip the 260 check when long paths are on.
The ninja that Android builds use comes from the CMake package installed by the Android SDK Manager. On our machine that's CMake 3.22.1, and its ninja.exe --version prints 1.10.2, a 2020 release that doesn't have the manifest. With that ninja, the registry setting changes nothing: the 260 limit stays.
We also saw a related failure. With a Gradle home in a long folder whose name contained an apostrophe, the build stopped earlier, in mergeReleaseResources, because the AAPT2 daemon wouldn't start. Short paths fix both.
The manual fix
1. Build from a short path
This is what made our builds pass. Put the project, or a copy of it, in a short folder at the root of a drive:
# Short folder, no spaces or special characters
mkdir C:\b
git clone https://example.com/your/repo.git C:\b\app
cd C:\b\app
npm ci
npx expo prebuild --platform android
How short is short enough? Our failing attempt had a 139-character project path. The passing one used a 10-character workspace. In WinBuild we settled on a limit of 40 characters, with letters, digits, ., - and _ only. That limit comes from a single app, so a project with deeper native modules might need even less. Avoid spaces and apostrophes.
If you'd rather keep working in your usual folder, use the short copy only for release builds. Copy the source, not node_modules or android, and regenerate those in the short folder.
2. Move the Gradle home to a short path too
By default the Gradle user home is %USERPROFILE%\.gradle, so it's under your user folder, with your user name in it. Point it somewhere short for the build session:
$env:GRADLE_USER_HOME = "C:\gh"
cd C:\b\app\android
.\gradlew.bat app:bundleRelease
The first build with a new Gradle home downloads all dependencies again, so expect it to be slower. Keep the same short home for later builds. Our passing builds used a short Gradle home; we haven't tested this step on its own.
3. Clean the old native build output
This is a precaution: paths from the long-folder attempt can stay in the CMake cache, so delete the generated folders before trying again:
Remove-Item -Recurse -Force C:\b\app\android\app\.cxx, C:\b\app\android\app\build
4. Optional: build fewer ABIs
The Expo template builds four ABIs by default (armeabi-v7a, arm64-v8a, x86, x86_64). This doesn't shorten any path, but it means fewer native builds that can hit the limit, and less time spent. For a Play release, the phone ABIs are usually enough:
.\gradlew.bat app:bundleRelease -PreactNativeArchitectures=arm64-v8a,armeabi-v7a
One caveat: an app without x86_64 crashes on a typical x86_64 emulator. To test on an emulator, include x86_64.
What about a newer ninja?
In theory, a ninja 1.12 or later, with LongPathsEnabled on, would not stop at 260. Android lets you point a module at another CMake (cmake.dir in local.properties, or a CMake version in build.gradle) and expects ninja on the PATH. We haven't tested this. Other tools in the native chain may have their own limits, and changing the registry is a machine-wide setting that needs an admin. The short path is the fix we've seen work.
How WinBuild handles it
WinBuild never builds in your project folder. It copies the project into a workspace you choose and runs prebuild and Gradle there. Before starting any process, it checks the path rules that got us past this error:
- The workspace can be at most 40 characters, with letters, digits,
.,-and_only, for exampleC:\wb\app1. Otherwisebundlestops immediately withWORKSPACE_PATH_UNSAFE.planalready reports the problem (WORKSPACE_PATH_UNSAFE_FOR_BUILD) before any copy, install or prebuild, which take minutes. - The Gradle home for each attempt is created under a short root you choose with
--gradle-root(at most 64 characters). - If a build still fails, the report names the category instead of leaving you to scroll through the log:
PATH_TOO_LONG,NATIVE_BUILDorAAPT2_DAEMON. When we tried it,NATIVE_BUILDandAAPT2_DAEMONcorrectly identified the two path failures above.
winbuild bundle --workspace C:\wb\app1 --gradle-root C:\wb --allow-config-code
Your source folder can stay wherever you like, and nothing is written to it. You do have to create the short root folder yourself, because WinBuild doesn't create folders at the root of a drive.
Sources
External sources consulted on 20 October 2026. Figures about WinBuild come from our own build records.
- ninja 1.10.2 source, disk_interface.cc
- ninja 1.12.0 source, disk_interface.cc
- ninja pull request #2225: longPathAware manifest
- ninja releases
- Microsoft: Maximum Path Length Limitation
- Android: Install and configure the NDK and CMake
- Expo SDK 57 template, android/gradle.properties
Private alpha
Building Expo Android releases on Windows?
WinBuild is in private alpha. Testers get the package directly and help validate different machines and Expo projects.