Skip to content

Cloudflare Pages Deployment - Troubleshooting & Solution Documentation

Status: ✅ RESOLVED Date: 2025-10-17 Workflow: docs-cloudflare.yml Issue: Artifact not found error causing deployment failure


Table of Contents

  1. Problem Summary
  2. Investigation Process
  3. Root Cause Analysis
  4. Solution Implemented
  5. Technical Details
  6. Lessons Learned
  7. Best Practices

Problem Summary

Initial Error

The Cloudflare Pages deployment workflow was failing with the following error in the Deploy job:

Error: Unable to download artifact(s): Artifact not found for name: documentation
Please ensure that your artifact is not expired and the artifact was uploaded
using a compatible version of toolkit/upload-artifact.

Symptoms

  • ✅ Build job reported "success"
  • ❌ Deploy job failed immediately when trying to download artifact
  • ❌ No artifact visible in GitHub Actions UI
  • ⚠️ 6000+ lines of mkdocs output but no actual HTML files generated

Impact

  • Documentation site not updating on Cloudflare Pages
  • No clear error messages indicating the real problem
  • Confusing failure point (deploy instead of build)

Investigation Process

Phase 1: Initial Diagnosis (Misdiagnosis)

Hypothesis: Artifact upload path was incorrect

Actions Taken: - Changed artifact path from ${{ github.workspace }}/var/docs/user to var/docs/user - Added verification steps to check if build directory exists - Result: ❌ Did not solve the problem

Why This Failed: - The path correction was valid but didn't address the root cause - The build directory simply didn't exist at all - We were treating a symptom, not the disease

Phase 2: Enhanced Diagnostics

Hypothesis: Build was succeeding silently without creating files

Actions Taken: 1. Added comprehensive verification step after build:

- name: Verify build output exists
  run: |
    if [ ! -d "var/docs/user" ]; then
      echo "❌ ERROR: Build directory NOT found"
      ls -la
      exit 1
    fi

  1. Added HTML file counting:
    HTML_COUNT=$(find var/docs/user -name "*.html" 2>/dev/null | wc -l)
    if [ "$HTML_COUNT" -eq 0 ]; then
      echo "❌ ERROR: No HTML files generated!"
      exit 1
    fi
    

Result: ✅ Successfully identified the real problem - Workflow now failed at the build job (correct failure point) - Clear error message: "Build directory NOT found" - Directory listing showed var/ didn't exist at all

Phase 3: Root Cause Discovery

Finding: The site_dir path in mkdocs.yml was not being created

Configuration in mkdocs.yml:

site_dir: ../../../../var/docs/user

Build command execution:

cd 03_INFRA/03_11_documentation_platform/03_11_01_user_documentation
mkdocs build --verbose

Path Resolution:

Working directory: /workspace/03_INFRA/03_11_documentation_platform/03_11_01_user_documentation
Relative path:     ../../../../var/docs/user
Should resolve to: /workspace/var/docs/user
Actual result:     NOT CREATED ❌

Why It Failed: - MkDocs with strict: false doesn't fail on path creation issues - The relative path traversal was not resolving correctly in CI environment - Build reported "success" despite not creating output directory - Thousands of warnings about missing files were ignored


Root Cause Analysis

Primary Cause

Relative path resolution failure in the GitHub Actions environment.

The site_dir: ../../../../var/docs/user path was: 1. Calculated relative to the mkdocs working directory 2. Not being created due to path resolution issues in the CI environment 3. Silently failing because strict: false in mkdocs.yml

Contributing Factors

  1. Silent Failures:
  2. strict: false in mkdocs.yml allowed build to "succeed" with errors
  3. No verification of build output before artifact upload
  4. Artifact upload with if-no-files-found: error never reached

  5. Misleading Error Location:

  6. Build job reported success ✅
  7. Deploy job failed ❌ (wrong place to fail)
  8. Error message focused on artifact, not build output

  9. Insufficient Logging:

  10. No verification that site_dir was created
  11. No count of generated files
  12. Exit code not checked after mkdocs build

Solution Implemented

Final Fix: Absolute Path Override

Change: Override the relative site_dir with an absolute path using the --site-dir flag

- name: Build documentation
  run: |
    cd 03_INFRA/03_11_documentation_platform/03_11_01_user_documentation

    # Override site_dir with absolute path
    mkdocs build --verbose --site-dir "${{ github.workspace }}/var/docs/user"

Why This Works: - ${{ github.workspace }} is guaranteed to be correct in GitHub Actions - No path traversal needed - Explicit, absolute path eliminates ambiguity - MkDocs will create parent directories as needed

Additional Improvements

  1. Enhanced Verification:

    - name: Verify build output exists
      run: |
        cd ${{ github.workspace }}
    
        # Check directory exists
        if [ ! -d "var/docs/user" ]; then
          echo "❌ ERROR: Build directory NOT found"
          exit 1
        fi
    
        # Count HTML files
        HTML_COUNT=$(find var/docs/user -name "*.html" | wc -l)
        if [ "$HTML_COUNT" -eq 0 ]; then
          echo "❌ ERROR: No HTML files generated!"
          exit 1
        fi
    
        echo "✅ Build successful: $HTML_COUNT HTML files"
    

  2. Better Logging:

    echo "Current directory: $(pwd)"
    echo "Target site_dir: ${{ github.workspace }}/var/docs/user"
    echo "Build command completed with exit code: $?"
    

  3. Explicit Artifact Path:

    - name: Upload build artifact
      uses: actions/upload-artifact@v4
      with:
        name: documentation
        path: var/docs/user  # Relative from workspace root
        retention-days: 1
        if-no-files-found: error
    


Technical Details

Workflow Architecture

┌─────────────────────────────────────────────────────────────┐
│ Job: Build Documentation                                     │
├─────────────────────────────────────────────────────────────┤
│ 1. Checkout repository                                      │
│ 2. Setup Python + dependencies                              │
│ 3. Configure Git (for git-authors plugin)                   │
│ 4. Build docs with ABSOLUTE path:                           │
│    mkdocs build --site-dir /workspace/var/docs/user         │
│ 5. Verify build output:                                     │
│    ✓ Directory exists                                       │
│    ✓ HTML files present                                     │
│    ✓ File count > 0                                         │
│ 6. Upload artifact: var/docs/user → "documentation"         │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ Job: Deploy to Cloudflare Pages                             │
├─────────────────────────────────────────────────────────────┤
│ 1. Download artifact: "documentation" → dist/               │
│ 2. Deploy to Cloudflare Pages from dist/                    │
│ 3. Generate deployment summary                              │
└─────────────────────────────────────────────────────────────┘

MkDocs Configuration

File: 03_INFRA/03_11_documentation_platform/03_11_01_user_documentation/mkdocs.yml

# Output Directory (now overridden by CLI flag in CI)
site_dir: ../../../../var/docs/user  # Used for local builds

# Build Configuration
strict: false  # Allows warnings (necessary for dev)

# Plugins that generate virtual files
plugins:
  - gen-files:        # Generates navigation from repo structure
      scripts:
        - scripts/gen_nav.py
  - literate-nav:     # Reads generated SUMMARY.md
  - section-index:    # README.md as section index pages
  - search:           # Full-text search

Key Insight: The gen-files plugin creates virtual files in memory during build, which are then written to site_dir. If site_dir isn't created correctly, the build appears to succeed but produces no output.

Path Resolution Comparison

Environment Working Dir site_dir Config Resolved Path Result
Local Windows C:\AudioDev\audio-lab\03_INFRA\...\03_11_01_user_documentation ../../../../var/docs/user C:\AudioDev\audio-lab\var\docs\user ✅ Works
GitHub Actions (Before) /workspace/03_INFRA/.../03_11_01_user_documentation ../../../../var/docs/user ❌ Not created Failed silently
GitHub Actions (After) /workspace/03_INFRA/.../03_11_01_user_documentation --site-dir /workspace/var/docs/user /workspace/var/docs/user Works

Lessons Learned

1. Fail Fast, Fail Loud

Problem: Build reported success despite producing no output

Lesson: Always verify critical outputs explicitly

# BAD: Trust the tool's exit code
mkdocs build

# GOOD: Verify the expected output
mkdocs build
if [ ! -f "site/index.html" ]; then
  echo "ERROR: Build produced no output"
  exit 1
fi

2. Absolute Paths in CI/CD

Problem: Relative paths behave differently across environments

Lesson: Use CI/CD variables for absolute paths

# BAD: Relative path traversal
site_dir: ../../../../output

# GOOD: Absolute path in CI
mkdocs build --site-dir "${{ github.workspace }}/output"

3. Error Context Matters

Problem: Error occurred in deploy job, real issue was in build job

Lesson: Validate outputs at the point of creation

# Build job should verify its own outputs
- name: Build
  run: make build

- name: Verify build output  # ← Critical verification step
  run: test -f dist/index.html || exit 1

- name: Upload artifact
  uses: actions/upload-artifact@v4
  with:
    if-no-files-found: error  # ← Redundant safety check

4. Silent Mode is Dangerous

Problem: strict: false hides critical errors

Lesson: Use strict mode in CI, relaxed mode in dev

# In mkdocs.yml (development)
strict: false

# In CI workflow (production)
mkdocs build --strict  # Override for CI

5. Diagnostic Logging

Problem: Hard to debug without context

Lesson: Log key information during builds

echo "Working directory: $(pwd)"
echo "Target output: $OUTPUT_DIR"
echo "Files generated: $(find $OUTPUT_DIR -type f | wc -l)"


Best Practices

For GitHub Actions Workflows

  1. Use Absolute Paths for Critical Directories

    - run: tool build --output "${{ github.workspace }}/dist"
    

  2. Verify Outputs Before Upload

    - run: |
        if [ ! -d "dist" ] || [ -z "$(ls -A dist)" ]; then
          echo "ERROR: No build output"
          exit 1
        fi
    

  3. Log Context Information

    - run: |
        echo "::group::Build Context"
        echo "Workspace: ${{ github.workspace }}"
        echo "Working dir: $(pwd)"
        echo "::endgroup::"
    

  4. Make Failures Explicit

    - run: |
        make build
        if [ $? -ne 0 ]; then
          echo "::error::Build failed"
          exit 1
        fi
    

For MkDocs Deployments

  1. Override site_dir in CI

    - run: mkdocs build --site-dir "${{ github.workspace }}/site"
    

  2. Use Strict Mode in Production

    - run: mkdocs build --strict --site-dir "$SITE_DIR"
    

  3. Validate Generated Files

    - run: |
        HTML_COUNT=$(find site -name "*.html" | wc -l)
        if [ "$HTML_COUNT" -eq 0 ]; then
          echo "ERROR: No HTML files generated"
          exit 1
        fi
        echo "Generated $HTML_COUNT HTML files"
    

  4. Check for Required Files

    - run: |
        test -f site/index.html || {
          echo "ERROR: Missing index.html"
          exit 1
        }
    

For Artifact Handling

  1. Use Descriptive Artifact Names

    name: documentation-${{ github.sha }}
    

  2. Set Appropriate Retention

    retention-days: 1  # For CI artifacts (short-lived)
    retention-days: 90 # For release artifacts (long-lived)
    

  3. Fail on Missing Files

    if-no-files-found: error  # Don't create empty artifacts
    

  4. Document Artifact Structure

    # Artifact "documentation" contains:
    # - index.html (entry point)
    # - assets/ (static files)
    # - search/ (search index)
    


Design Recommendations

Multi-Environment Path Strategy

# In mkdocs.yml (default for local dev)
site_dir: ../../../../var/docs/user

# In GitHub Actions (override for CI)
env:
  SITE_DIR: ${{ github.workspace }}/var/docs/user

- run: mkdocs build --site-dir "$SITE_DIR"

Comprehensive Build Verification

- name: Verify build output
  run: |
    SITE_DIR="${{ github.workspace }}/var/docs/user"

    # Check directory exists
    [ -d "$SITE_DIR" ] || {
      echo "::error::Site directory not created"
      exit 1
    }

    # Check index.html exists
    [ -f "$SITE_DIR/index.html" ] || {
      echo "::error::Missing index.html"
      exit 1
    }

    # Count files
    FILE_COUNT=$(find "$SITE_DIR" -type f | wc -l)
    HTML_COUNT=$(find "$SITE_DIR" -name "*.html" | wc -l)

    echo "::notice::Build generated $HTML_COUNT HTML files ($FILE_COUNT total)"

    # Require minimum files
    [ "$HTML_COUNT" -gt 0 ] || {
      echo "::error::No HTML files generated"
      exit 1
    }

Error Message Design

- run: |
    if ! mkdocs build --site-dir "$SITE_DIR"; then
      echo "::error title=MkDocs Build Failed::Check logs above for details"
      echo "::group::Diagnostics"
      echo "Working directory: $(pwd)"
      echo "Python version: $(python --version)"
      echo "MkDocs version: $(mkdocs --version)"
      echo "::endgroup::"
      exit 1
    fi

Summary

What We Fixed

Issue Solution Impact
Relative path not resolving Use --site-dir with absolute path ✅ Build creates output
Silent build failures Add explicit output verification ✅ Fail fast with clear errors
Wrong failure point Verify in build job, not deploy ✅ Fail at correct step
Unclear error messages Add diagnostic logging ✅ Easy troubleshooting
Artifact not created Verify files before upload ✅ Deploy job gets artifact

Final Workflow State

  • ✅ Build job creates HTML files in correct location
  • ✅ Verification step catches failures early
  • ✅ Clear error messages when things go wrong
  • ✅ Artifact uploads successfully
  • ✅ Deploy job downloads and deploys correctly
  • ✅ Documentation site updates on Cloudflare Pages

Key Takeaway

The journey from "it says success" to "it actually works" requires: 1. Explicit verification of expected outputs 2. Absolute paths in CI environments 3. Failing fast and loud when something's wrong 4. Logging context for easy debugging 5. Testing assumptions at every step


References


Document Status: ✅ Complete Last Updated: 2025-10-17 Maintained By: AudioLab Infrastructure Team