Azure DevOps React Build Fails with “Not found PathtoPublish”: The Ultimate Fix for CRA & Vite

The "Not found PathtoPublish" error in Azure DevOps is a critical pipeline failure that occurs when the deployment agent attempts to publish your built application, but cannot locate the compiled output folder it was instructed to find. Essentially, the pipeline is looking for your final, minified production files (like your JavaScript, CSS, and HTML) in a specific directory—usually /build—but the folder is either missing, empty, or named differently.

Introduction

It is a classic late-Friday deployment scenario. You push your code, watch the Azure DevOps pipeline spin up, and stare at the console. The checkout succeeds. The npm install completes perfectly. The build step gets a satisfying green checkmark. Everything looks flawless.

But right at the final hurdle—the artifact publishing stage—the pipeline aggressively fails with one of the most frustrating and misunderstood errors in modern CI/CD:

Publishing build artifacts failed with an error: Not found PathtoPublish: /home/vsts/work/1/s/build

As a DevOps engineer, I see this issue constantly. It creates an illusion: the pipeline tells you the build was successful, but the actual compiled output you need to deploy simply does not exist.

In this comprehensive guide, we are going to tear down exactly why Azure DevOps throws this error, the massive shift in the React ecosystem causing it, and how to configure your YAML pipelines properly for both Create React App (CRA) and modern Vite applications.


Deconstructing the Error: What Does PathtoPublish Actually Mean?

To fix a problem permanently, you have to understand the mechanics of the build agent. When an Azure Pipeline runs, it checks your code out into a temporary workspace on a virtual machine (usually an Ubuntu agent). This workspace is represented by the predefined system variable $(System.DefaultWorkingDirectory).

The task responsible for saving your compiled code—usually PublishBuildArtifacts@1 or the newer PublishPipelineArtifact@1—does not compile code itself. It is a completely blind courier. It takes whatever folder path you give it in the PathtoPublish target, zips it up, and attaches it to the pipeline run so your Release pipeline can grab it later.

If the agent reaches that step and the folder doesn't exist, it throws the fatal error. This means we are dealing with a silent build failure. Your Node.js step didn't fail, but it also didn't produce the directory Azure DevOps was expecting.


The First Culprit: The "npm build" vs. "npm run build" Trap

Before blaming your framework, we must look at the most common pipeline misconfiguration: the build command itself. In the rush to set up CI/CD, many developers write out the pipeline tasks manually and make a critical syntax error.

If your pipeline contains this command:

- script: npm build
  displayName: 'Build React App'

This will not build your application. In NPM, install and test are top-level commands, but build is not. To execute the build script defined inside your package.json, you absolutely must use the run keyword. Without it, NPM does practically nothing, exits with a success code (0), and leaves you with no output folder, causing the artifact step to crash moments later.

The Second Culprit: The Great Migration from CRA to Vite

If your build command is perfectly fine (npm run build) and you are still getting the error, you have likely fallen victim to the modern JavaScript tooling shift.

For years, Create React App (CRA) was the undisputed king of React development. When you run a build in a CRA project via Webpack, it compiles your minified JavaScript, CSS, and HTML into a folder explicitly named build/. Because CRA was so dominant, almost all legacy Azure DevOps templates, Stack Overflow answers, and corporate YAML snippets default to looking for a folder named build.

However, the industry has aggressively moved to Vite due to its incredibly fast Hot Module Replacement (HMR) and optimized Rollup builds. Here lies the root of the issue: Vite outputs its compiled production files into a folder named dist/ (short for distribution), not build/.

If your codebase is Vite-powered, but your Azure DevOps pipeline is copy-pasted from an old CRA project, the pipeline will successfully compile to /dist, and then aggressively crash when the artifact step goes hunting for /build.


The Step-by-Step Fix: Writing the Correct YAML Pipeline

Now that we understand the underlying mechanics, let's write a bulletproof, production-ready YAML configuration that correctly builds and publishes your application.

Step 1: Ensure the Correct Build Execution

First, verify your Node task is explicitly calling the script correctly using npm run build or yarn build.

Step 2: Align the Publish Task with Your Bundler

Update the targetPath (or PathtoPublish in classic UI) to match your specific toolchain.

For a Modern Vite Application:

- task: PublishPipelineArtifact@1
  inputs:
    targetPath: '$(System.DefaultWorkingDirectory)/dist'
    artifact: 'drop'
    publishLocation: 'pipeline'
  displayName: 'Publish Vite Artifact (dist)'

For a Legacy Create React App (CRA):

- task: PublishPipelineArtifact@1
  inputs:
    targetPath: '$(System.DefaultWorkingDirectory)/build'
    artifact: 'drop'
    publishLocation: 'pipeline'
  displayName: 'Publish CRA Artifact (build)'

Pro DevOps Tip: Implement a "Sanity Check" Debug Task

When configuring pipelines for the first time, never guess what the virtual machine is doing. If you are experiencing path issues, inject a simple bash script directly before your publish step. This will print the entire directory tree into your Azure DevOps logs, allowing you to physically see exactly where your files ended up.

- script: |
    echo "--- CURRENT DIRECTORY PATH ---"
    pwd
    echo "--- ROOT REPOSITORY CONTENTS ---"
    ls -la
    echo "--- CHECKING FOR VITE DIST FOLDER ---"
    ls -la dist || echo "DIST FOLDER NOT FOUND!"
    echo "--- CHECKING FOR CRA BUILD FOLDER ---"
    ls -la build || echo "BUILD FOLDER NOT FOUND!"
  displayName: 'DevOps Debug: Inspect Workspace'

Running this task will immediately reveal if your npm run build failed silently, or if the folder is nested one level deeper than you anticipated.

After applying the correct directory mapping, verifying your Azure DevOps pipeline publish artifact success logs becomes a satisfying confirmation of your fix. Successfully publishing build artifacts without the dreaded PathToPublish error means your React or Vite application is fully compiled, zipped, and securely attached to the pipeline run, ready for seamless deployment to your hosting environment.


Extra Tips for Pipeline Success

  • Match Node Versions: Ensure your Azure Pipeline is using the exact same Node.js version as your local development environment by adding the NodeTool@0 task before your npm install step.
  • Cache Dependencies: Use the Cache@2 task to cache your node_modules folder. This can shave minutes off your build time by avoiding fresh downloads for unchanged dependencies.
  • Clean Your Workspaces: If you use self-hosted DevOps agents, configure the pipeline to clean the workspace before building. Stale files from previous runs are notorious for causing false positives!

Final Thoughts for Reliable Deployments

In the world of continuous integration and continuous deployment, "magic" doesn't exist. Every failure has a logical path. The “Not found PathtoPublish” error is rarely a failure of Azure DevOps itself; rather, it is a mismatch between the pipeline’s expectations and your local frontend tooling framework.

By strictly enforcing the correct NPM commands, understanding the architectural differences between Webpack (CRA) and Rollup (Vite), and utilizing Azure DevOps system variables to map absolute paths, you can permanently eliminate this error from your CI/CD workflows.

Once your artifacts are reliably publishing, your Release pipelines can pull down that dist folder and deploy it to Azure App Services, AWS S3, or Nginx Linux servers with absolute confidence.

f X W