Table of Contents

    Book an Appointment

    HOW DID WE DISCOVER THE REACT NATIVE ANDROID BUILD FAILED ISSUE?

    While working on a feature-rich cross-platform mobile learning application for the EdTech sector, we hit a significant roadblock. The application was designed to handle high-performance mathematical rendering, custom graph drawing and smooth 60fps animations. To achieve this, the architecture relied heavily on Expo and deeply integrated C++ based native libraries like Skia and Nitro Modules.

    Everything ran flawlessly during our local web testing. However, when we attempted to compile the application for an Android emulator on a Windows 11 development machine, we were immediately halted. The terminal threw a massive block of red text and our react native android build failed abruptly.

    In production-grade mobile engineering, build reliability is paramount. When local builds fail due to environment-specific native compilation errors, it stalls the entire CI/CD pipeline and blocks developer velocity. This specific challenge—debugging C++ CMake compilation errors on a Windows host—inspired this article so that other teams can avoid the same frustrating pitfalls when configuring modern native modules.

    WHAT WAS THE ARCHITECTURAL CONTEXT BEHIND THIS NATIVE MODULE FAILURE?

    The business use case demanded an interactive student dashboard capable of rendering complex visualizations (hence the inclusion of Skia) alongside multithreaded background tasks (utilizing native Worklets). The architecture was built on React Native 0.83, utilizing the new architecture and a strict PNPM monorepo structure.

    In modern React Native ecosystems, modules like Skia, Worklets and Nitro are not just standard JavaScript packages. They include heavy C++ codebases that must be compiled into native shared libraries (.so files) for Android via the Android NDK (Native Development Kit). Gradle orchestrates this process using CMake and Prefab (a tool for generating native build scripts and managing C++ dependencies).

    The issue surfaced exactly at the intersection where the Gradle build system attempts to invoke the Windows command line to execute auto-generated CMake batch scripts. For teams looking to scale such complex architectures, choosing to hire software developer teams with deep knowledge of cross-platform build pipelines is highly recommended.

    WHAT EXACTLY WENT WRONG WITH CMAKE AND PREFAB?

    When running the local build command, the process crashed with four distinct task failures. The core symptoms were centered around configuring CMake for the arm64-v8a architecture.

    Here is a sanitized version of the stack trace we encountered:

    Execution failed for task ':react-native-nitro-modules:configureCMakeDebug[arm64-v8a]'.
    > [CXX1428] exception while building Json A problem occurred starting process 'command 'C:UsersdevOneDriveDocumentsprojectsappnode_modules.pnpmreact-native-nitro-modules@_7b0f...node_modulesreact-native-nitro-modulesandroidbuildintermediatescxxDebug6n21531jlogsarm64-v8aprefab_command.bat'' 
      ...
      Caused by: java.io.IOException: Cannot run program "C:UsersdevOneDriveDocumentsprojectsappnode_modules.pnpmreact-native-nitro-modules@_7b0f...node_modulesreact-native-nitro-modulesandroidbuildintermediatescxxDebug6n21531jlogsarm64-v8aprefab_command.bat": CreateProcess error=2, The system cannot find the file specified
    

    The logs revealed similar failures for shopify_react-native-skia, react-native-screens and react-native-worklets. The critical clue was CreateProcess error=2, The system cannot find the file specified. Gradle was trying to execute a prefab_command.bat file to configure the C++ libraries, but the underlying Windows OS claimed the file did not exist, even though the build process had just attempted to generate it.

    HOW DID WE APPROACH SOLVING THE CREATEPROCESS ERROR=2?

    A “file not found” error during an automated build process typically points to one of three things: missing dependencies, symlink resolution failures or OS-level file path limitations. We methodically investigated each possibility.

    DID WE MISS THE NDK AND CMAKE INSTALLATIONS?

    Our first assumption was that the environment lacked the necessary build tools. C++ compilation requires the Android NDK and CMake. We opened the Android Studio SDK Manager and verified that both CMake and the NDK were installed and properly mapped in the local.properties file. Since the tools were present, we ruled out a missing installation.

    COULD PNPM SYMLINKS BE BREAKING THE BUILD?

    Modern package managers like PNPM use symlinks to maintain a flat node_modules directory while keeping the actual packages in a hidden .pnpm virtual store. While highly efficient, the React Native Gradle plugin and Metro bundler historically struggle with deeply nested symlinks. We considered switching completely to Yarn or npm, but rewriting the package manager strategy for an entire monorepo is a disruptive tradeoff. We needed a less invasive solution.

    WERE WINDOWS PATH LENGTH LIMITS TO BLAME?

    We looked closer at the failed file path in the logs. By default, the Windows API limits file paths to 260 characters (MAX_PATH). When we counted the characters in the path to the prefab_command.bat file, it exceeded 280 characters. This happened due to a combination of three factors:

    • The project was located inside a deeply nested user directory (and synced via OneDrive, adding cloud-sync file locking to the mix).
    • PNPM’s strict package resolution creates long directory names containing versions and hashes (e.g., .pnpmreact-native-nitro-modules@_7b0f...).
    • The Android Gradle plugin generates deeply nested intermediate build folders (buildintermediatescxxDebug...).

    Because the path exceeded 260 characters, Windows silently failed to create or read the .bat file, causing the CreateProcess error=2.

    WHAT WAS THE FINAL IMPLEMENTATION TO FIX THE ANDROID BUILD?

    To resolve the issue permanently, we implemented a multi-layered fix targeting the Windows environment and the package manager configuration.

    Step 1: Relocating the Project and Avoiding Cloud Sync

    We immediately moved the project repository out of the OneDrive/Documents folder directly into a shallow directory at the root of the C: drive (e.g., C:srcapp). This eliminated both the path bloat and the aggressive file-locking behavior of cloud backup software.

    Step 2: Enabling Windows Long Path Support

    We enabled Long Paths in the Windows Registry to prevent future MAX_PATH limits from interfering with deeply nested C++ build artifacts. This is done by opening an Administrator PowerShell prompt and running:

    New-ItemProperty -Path "HKLM:SYSTEMCurrentControlSetControlFileSystem" -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force
    

    Step 3: Configuring PNPM for React Native Compatibility

    To prevent Gradle from failing to resolve symlinked native dependencies, we configured PNPM to use hoisted node modules. We created an .npmrc file at the root of the project with the following configuration:

    node-linker=hoisted
    public-hoist-pattern[]=*react-native*
    public-hoist-pattern[]=*expo*

    After applying these changes, we wiped the cached build folders, regenerated the node modules and triggered the build:

    rmdir /s /q node_modules
    rmdir /s /q android.gradle
    rmdir /s /q androidappbuild
    pnpm install
    npx expo run:android -c

    The CMake configuration succeeded, the C++ modules compiled and the Android build completed successfully.

    WHAT ARE THE CORE LESSONS FOR ENGINEERING TEAMS?

    Diagnosing build failures in cross-platform environments requires patience and an understanding of the underlying OS constraints. Here are the key takeaways for teams looking to hire react native developers for cross-platform apps:

    • Beware of Windows MAX_PATH: Always enable LongPathsEnabled on Windows development machines when dealing with Node.js and Gradle ecosystems.
    • Keep Workspaces Shallow: Never clone repositories into deeply nested directories. Stick to C:projects or ~/src/.
    • Avoid Cloud-Synced Folders: Building heavy C++ or Node projects inside OneDrive, Dropbox or iCloud folders will inevitably cause file-locking and “file not found” errors during high-speed build I/O.
    • Package Manager Quirks: PNPM is incredibly fast, but its symlink strategy can break native Android builds. Use node-linker=hoisted when working with React Native.
    • Analyze the Full Stack Trace: Gradle errors often look like C++ failures ([CXX1428] exception while building Json), but the root cause is usually found deeper in the Java/OS interaction (CreateProcess error=2).

    When enterprise companies decide to hire mobile app developers to build native experiences, it is this level of troubleshooting and architectural understanding that ensures predictable project delivery.

    HOW CAN WE WRAP UP THIS CMAKE CONFIGURATION CHALLENGE?

    What initially looked like a severe incompatibility between React Native native modules and the Android NDK turned out to be a classic OS-level file path limitation exacerbated by modern package management. By streamlining the directory structure, modifying Windows registry policies and adjusting PNPM hoisting rules, we stabilized the local development environment and unblocked the team.

    If your engineering organization is struggling with complex cross-platform build pipelines, infrastructure setup or requires seasoned architects to untangle CI/CD bottlenecks, contact us. Our pre-vetted teams bring deep, real-world expertise to every technical challenge.

    Social Hashtags

    #ReactNative #AndroidDevelopment #CMake #ReactNativeDevelopment #BuildErrors #AndroidStudio #Expo #PNPM #MobileAppDevelopment #Cpp #Windows11 #SoftwareDevelopment #Gradle #DevOps #ReactNativeTips

    Frequently Asked Questions