Cloudflare Pages Deployment - Troubleshooting & Solution Documentation¶
Status: ✅ RESOLVED Date: 2025-10-17 Workflow:
docs-cloudflare.ymlIssue: Artifact not found error causing deployment failure
Table of Contents¶
- Problem Summary
- Investigation Process
- Root Cause Analysis
- Solution Implemented
- Technical Details
- Lessons Learned
- 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
- Added HTML file counting:
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:
Build command execution:
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¶
- Silent Failures:
strict: falsein mkdocs.yml allowed build to "succeed" with errors- No verification of build output before artifact upload
-
Artifact upload with
if-no-files-found: errornever reached -
Misleading Error Location:
- Build job reported success ✅
- Deploy job failed ❌ (wrong place to fail)
-
Error message focused on artifact, not build output
-
Insufficient Logging:
- No verification that
site_dirwas created - No count of generated files
- 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¶
-
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" -
Better Logging:
-
Explicit Artifact Path:
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¶
-
Use Absolute Paths for Critical Directories
-
Verify Outputs Before Upload
-
Log Context Information
-
Make Failures Explicit
For MkDocs Deployments¶
-
Override
site_dirin CI -
Use Strict Mode in Production
-
Validate Generated Files
-
Check for Required Files
For Artifact Handling¶
-
Use Descriptive Artifact Names
-
Set Appropriate Retention
-
Fail on Missing Files
-
Document Artifact Structure
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¶
- GitHub Actions: Storing workflow data
- MkDocs Configuration
- Cloudflare Pages Action
- Workflow Run #44 - First successful deployment
Document Status: ✅ Complete Last Updated: 2025-10-17 Maintained By: AudioLab Infrastructure Team