The upload-artifact GitHub Actions workflow step is failing because the specified file or directory path doesn’t exist on the runner at the time the action runs.
Here’s what’s actually breaking: The actions/upload-artifact action is a separate process from your main job’s code execution. When it’s time for upload-artifact to run, it looks for the files you told it to upload at the path you provided. If that path is empty or points to something that was deleted or never created by a previous step, upload-artifact can’t find anything to upload and throws this error. It’s like asking someone to mail a package, but you haven’t put anything in the box before handing it to them.
Common Causes and Fixes:
-
Artifact Path Typo or Incorrect Name:
- Diagnosis: Double-check the
pathparameter in yourupload-artifactstep against the actual directory or file name created in a previous step. Case sensitivity matters! - Fix: Correct the
pathvalue. For example, if a previous step created a directory namedbuild-output, yourupload-artifactstep should look like:- name: Upload build output uses: actions/upload-artifact@v3 with: name: my-build-artifacts path: build-output - Why it works: Ensures the action is looking for the artifact at the precisely correct location.
- Diagnosis: Double-check the
-
Artifact Not Created in Time (Race Condition):
- Diagnosis: If the artifact is generated by a preceding step, ensure that step has completed successfully and actually created the files before the
upload-artifactstep begins. Sometimes, asynchronous operations or complex build processes can lead to the artifact directory being empty whenupload-artifactchecks. - Fix: Ensure the
upload-artifactstep hasneedsset to the step that generates the artifact, or that it’s part of the same job and runs sequentially after the generation step. If the generation is complex, consider adding a simplelsorechocommand in a step right beforeupload-artifactto print the contents of the expected directory to the logs for verification.- name: Verify artifact directory contents run: | echo "Contents of ./build-output:" ls -la ./build-output - Why it works: Explicitly confirms the artifact exists and is accessible before attempting to upload it, and ensures the upload step waits for generation.
- Diagnosis: If the artifact is generated by a preceding step, ensure that step has completed successfully and actually created the files before the
-
Incorrect Working Directory:
- Diagnosis: The
pathis relative to the runner’s current working directory. If your build process or subsequent steps change the working directory (working-directoryin a step orcdcommands in a script), thepathmight be looking in the wrong place. - Fix: Either specify an absolute path (less common and less portable) or ensure the
pathis relative to the expected working directory of theupload-artifactstep. You can explicitly set theworking-directoryfor theupload-artifactstep if needed, or ensure your previous steps don’t change it unexpectedly.- name: Build and Archive run: | mkdir my-app-files echo "some content" > my-app-files/config.txt working-directory: ./src # Example: build happens in ./src - name: Upload artifact uses: actions/upload-artifact@v3 with: name: config-files path: ./src/my-app-files # Path relative to repo root - Why it works: Aligns the path lookup with where the files are actually located on the runner’s filesystem.
- Diagnosis: The
-
Artifact Path is a File, Not a Directory (or vice-versa):
- Diagnosis: The
upload-artifactaction can upload both files and directories. However, if you specify a path that looks like a directory but is actually a file, or vice-versa, it might behave unexpectedly depending on the action’s internal logic and the exact version. More critically, if the path you specify should be a directory but contains no files, it will also fail. - Fix: Ensure the
pathcorrectly points to the intended entity. If you intend to upload a single file namedresults.json, the path should beresults.json. If you intend to upload everything in a directory calledoutput, the path should beoutput. Ifoutputis empty, you’ll still get an error. Add a check to ensure files are present.- name: Generate report run: | echo "Report content" > my_report.txt - name: Check if report exists run: | if [ ! -f "my_report.txt" ]; then echo "Error: my_report.txt not found!" exit 1 fi - name: Upload report uses: actions/upload-artifact@v3 with: name: report path: my_report.txt - Why it works: Verifies the existence and type of the artifact before attempting to upload, and clarifies whether you’re uploading a file or its containing directory.
- Diagnosis: The
-
Conditional Logic Skipping Artifact Creation:
- Diagnosis: If the step that creates the artifact is skipped due to
ifconditions (e.g.,if: github.ref == 'refs/heads/main'), but theupload-artifactstep is not also guarded by the same condition,upload-artifactwill run and find nothing. - Fix: Ensure that any
ifconditions that prevent artifact creation also prevent theupload-artifactstep from running.jobs: build: runs-on: ubuntu-latest if: github.ref == 'refs/heads/main' # Job only runs on main branch steps: - name: Checkout code uses: actions/checkout@v3 - name: Build run: echo "Building..." # This step runs because the job condition passes - name: Upload artifact uses: actions/upload-artifact@v3 with: name: build-output path: ./build # This path is created by the 'Build' step - Why it works: Prevents the upload action from executing when the artifact it’s supposed to upload hasn’t been generated.
- Diagnosis: If the step that creates the artifact is skipped due to
-
Runner Environment Differences:
- Diagnosis: While less common, if your build process relies on specific tools or configurations that are present on your local machine but missing from the GitHub Actions runner, the artifact might not be created as expected.
- Fix: Ensure your workflow
runs-ona runner type that has all necessary dependencies installed. You might need to useactions/setup-node,actions/setup-python, etc., or install tools manually within yourrunsteps.jobs: build: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v3 - name: Set up Node.js uses: actions/setup-node@v3 with: node-version: '18' - name: Build with Node run: npm ci && npm run build # This creates the 'dist' directory - name: Upload build artifacts uses: actions/upload-artifact@v3 with: name: web-app path: dist # Assuming your build output is in 'dist' - Why it works: Guarantees the environment has the necessary software to successfully execute the build steps that create the artifact.
The next error you’ll likely see if you fix this is a "Permissions denied" error when trying to upload if the artifact path is a directory but contains files that the runner doesn’t have read access to, or a general "Upload failed" with a more obscure HTTP error code if the artifact itself is somehow corrupted or too large for the configured limits.