When Capacitor sync fails before it starts
A failed Android sync does not always mean the Android project is broken. On Windows, the failure can happen one layer earlier: the package runner cannot resolve the local Capacitor executable. Treating that as a Gradle or Capacitor configuration issue wastes time because neither tool has started yet.
Identify the failing layer
Read the first meaningful error, not the final summary. If the output says that cap is not recognized, cannot be resolved, or is missing, the immediate problem is executable discovery. A real Capacitor sync failure normally prints Capacitor activity such as copying web assets or updating Android plugins. A real Gradle failure normally includes tasks, dependency resolution or Java output.
Before changing configuration, verify three things:
- The project contains
node_modules. - The Capacitor CLI is declared in the project dependencies.
- The Windows command shim exists under
node_modules\.bin.
Call the local executable directly
Package runners are convenient, but direct invocation removes one resolution layer. From PowerShell in the project root, use:
.\node_modules\.bin\cap.CMD sync androidThe .CMD suffix matters on Windows. The leading .\ tells PowerShell to execute a file from the current directory tree rather than search the global command path.
Do not stop at “sync completed”
A successful sync proves that Capacitor copied and updated the native project. It does not prove that the app builds, installs or launches. Verification should follow the user-visible path:
- Build the web application.
- Run the Capacitor sync with the local executable.
- Build the Android package.
- Confirm the expected signing configuration.
- Install the package on a connected device with the Android debugging tools.
- Launch the app and inspect the current activity or runtime log.
This sequence separates five distinct failure zones: web compilation, bridge synchronization, native compilation, installation and runtime behavior.
Make the repair repeatable
If the direct command is the reliable route on the target machine, encode it in a project script rather than relying on someone to remember it. Keep the script platform-aware if the repository is also used on macOS or Linux. Document the working Node and Java versions and retain the lockfile so the next installation resolves the same dependency graph.
The useful lesson is broader than Capacitor: classify the layer that failed before editing the layer you suspect. A command that never started cannot have produced a framework bug.