Skip to content

Documentation System Troubleshooting Guide

Version: 2.1 | Last Updated: 2026-01-06 | Status: Stable

Overview

This guide provides solutions to common problems when using the MBPanel documentation system. Covers MkDocs build issues, mkdocstrings parsing errors, cache corruption, git hook problems, and CI/CD failures.

Problem Resolution Flowchart

graph TD
    A[Documentation Problem] --> B{Can build locally?}
    B -->|Yes| C[Git or CI issue]
    B -->|No| D{Error type?}

    D -->|MkDocs build error| E[MkDocs Issue]
    D -->|mkdocstrings error| F[mkdocstrings Issue]
    D -->|Cache error| G[Cache Issue]
    D -->|Hook error| H[Git Hook Issue]

    C --> I[Check Git hooks]
    C --> J[Review CI configuration]

    E --> K[Check mkdocs.yml syntax]
    E --> L[Verify file paths]

    F --> M[Check Python syntax]
    F --> N[Review docstrings]

    G --> O[Clear cache]
    G --> P[Rebuild index]

    H --> Q[Reinstall hooks]
    H --> R[Check permissions]

    style A fill:#ffecb3
    style E fill:#ffcdd2
    style F fill:#ffcdd2
    style G fill:#fff9c4
    style H fill:#e1bee7

MkDocs Build Issues

Problem: "Config value error" in mkdocs.yml

Symptom:

ERROR: Config value error: 'plugins' (line 58)

Diagnosis: - YAML syntax error in mkdocs.yml - Plugin not installed - Incorrect plugin configuration

Resolution:

  1. Validate YAML syntax:

    # Install yamllint
    pip install yamllint
    
    # Check mkdocs.yml
    yamllint docs/mkdocs.yml
    

  2. Check plugin installation:

    # Verify required plugins installed
    pip list | grep -E "(mkdocs|mkdocstrings)"
    
    # Expected output:
    # mkdocs-material 9.5.0
    # mkdocstrings 0.24.0
    # mkdocs-section-index 0.3.0
    

  3. Fix common YAML errors:

    # WRONG - inconsistent indentation
    plugins:
      - search:
          lang: en
        separator: '[\s\-,:]+'  # Wrong indent
    
    # CORRECT
    plugins:
      - search:
          lang: en
          separator: '[\s\-:,]+'
    

  4. Reinstall if missing:

    pip install --upgrade mkdocs-material mkdocstrings[python] mkdocs-section-index
    

Problem: "Page not found" errors

Symptom:

WARNING: Nav item 'architecture/adr/index.md' does not exist

Diagnosis: - File path in mkdocs.yml doesn't match actual file - File not committed to git - Case sensitivity issue (Linux)

Resolution:

  1. Verify file exists:

    # Check if file exists
    ls -la docs/architecture/adr/index.md
    
    # Find similar files
    find docs -name "index.md" | grep adr
    

  2. Check case sensitivity:

    # Linux is case-sensitive
    # "ADR" != "adr"
    ls docs/architecture/  # List actual directory names
    

  3. Update mkdocs.yml with correct path:

    nav:
      - Architecture:
        # Verify this matches actual file
        - ADR: architecture/adr/index.md  # Ensure lowercase
    

  4. Stage and commit:

    git add docs/architecture/adr/index.md
    git commit -m "Fix: Add missing ADR index"
    

Problem: Build fails with "Template not found"

Symptom:

jinja2.exceptions.TemplateNotFound: adr.md.j2

Diagnosis: - Template file missing - Template directory not configured - Wrong template path in code

Resolution:

  1. Verify template exists:

    # List templates
    ls -la tools/docs/templates/
    
    # Expected output:
    # adr.md.j2
    # prd.md.j2
    # add.md.j2
    # task.md.j2
    # implementation.md.j2
    # error.md.j2
    

  2. Check template directory configuration:

    # In generator code, verify:
    from pathlib import Path
    
    templates_dir = Path(__file__).parent.parent / "templates"
    template_path = templates_dir / "adr.md.j2"
    
    if not template_path.exists():
        raise FileNotFoundError(f"Template not found: {template_path}")
    

  3. Recreate template if missing:

    # Copy from backup or recreate
    cat > tools/docs/templates/adr.md.j2 << 'EOF'
    # ADR {{ number }}: {{ title }}
    
    **Status:** {{ status }}
    **Date:** {{ date }}
    
    ## Context
    {{ context }}
    
    ## Decision
    {{ decision }}
    
    ## Consequences
    {{ consequences }}
    {% if alternatives %}
    ## Alternatives Considered
    {% for alt in alternatives %}
    ### {{ alt.name }}
    {{ alt.description }}
    **Pros:**
    {% for pro in alt.pros %}
    - {{ pro }}
    {% endfor %}
    **Cons:**
    {% for con in alt.cons %}
    - {{ con }}
    {% endfor %}
    {% endfor %}
    {% endif %}
    {% if related_documents %}
    ## Related Documents
    {% for doc in related_documents %}
    - [{{ doc.title }}]({{ doc.link }}) ({{ doc.type }})
    {% endfor %}
    {% endif %}
    
    ---
    
    *This ADR was created on {{ created_at }}*
    EOF
    

mkdocstrings Parsing Errors

Problem: "ImportError" when generating API docs

Symptom:

ModuleNotFoundError: No module named 'app.domains.sites'

Diagnosis: - Module not in Python path - Circular import - Missing dependency

Resolution:

  1. Set PYTHONPATH:

    # Add backend to Python path
    export PYTHONPATH=/path/to/mbpanelapi/backend:$PYTHONPATH
    
    # Then run command
    python -m tools.docs.cli generate-api-docs -m app.domains.sites.service
    

  2. Install backend package:

    cd backend
    pip install --no-deps -c constraints.txt -e .
    

  3. Check for circular imports:

    # Use Python to detect circular imports
    python -c "
    import sys
    sys.path.insert(0, 'backend')
    try:
        import app.domains.sites.service
    except ImportError as e:
        print(f'Import error: {e}')
        print('Possible circular import')
    "
    

Problem: "AttributeError" when rendering docstrings

Symptom:

AttributeError: module 'app' has no attribute 'domains'

Diagnosis: - Module structure changed - Incorrect module path - Missing init.py

Resolution:

  1. Verify module structure:

    # Check directory structure
    tree backend/app/domains/ -L 2
    
    # Expected:
    # backend/app/domains/
    # ├── __init__.py
    # ├── sites/
    # │   ├── __init__.py
    # │   ├── domain.py
    # │   ├── service.py
    # │   └── ...
    

  2. Test import:

    python -c "
    import sys
    sys.path.insert(0, 'backend')
    from app.domains.sites import service
    print('Import successful')
    print(dir(service))
    "
    

  3. Use correct module path:

    # WRONG
    python -m tools.docs.cli generate-api-docs -m sites.service
    
    # CORRECT
    python -m tools.docs.cli generate-api-docs -m app.domains.sites.service
    

Problem: mkdocstrings generates empty docs

Symptom: - API docs file created but empty - Only module title, no content

Diagnosis: - No docstrings in module - Docstring style mismatch - Private module (all names start with _)

Resolution:

  1. Check for docstrings:

    # Verify docstrings exist
    python -c "
    import sys
    sys.path.insert(0, 'backend')
    from app.domains.sites import service
    
    print('Module docstring:', service.__doc__)
    print('Classes:', [c for c in dir(service) if not c.startswith('_')])
    "
    

  2. Verify docstring style:

    # CORRECT - Google style (configured in mkdocs.yml)
    def create_site(name: str) -> Site:
        """Create a new site.
    
        Args:
            name: Site name
    
        Returns:
            Created site instance
    
        Raises:
            SiteAlreadyExists: If site already exists
        """
        pass
    
    # WRONG - No docstring
    def create_site(name: str) -> Site:
        pass
    

  3. Check mkdocstrings configuration:

    # In mkdocs.yml
    plugins:
      - mkdocstrings:
          handlers:
            python:
              options:
                docstring_style: google  # Must match docstring format
                show_source: true
                show_root_heading: true
    

Cache Corruption Issues

Problem: Build cache returns stale data

Symptom: - Changes not reflected in output - Old template used despite updates - File says "cached" but is outdated

Diagnosis: - Cache not invalidated properly - Cache file corrupted - Concurrent write corrupted cache

Resolution:

  1. Clear cache completely:

    # Use CLI
    python -m tools.docs.cli cache-clear
    
    # Or manually remove
    rm docs/.build_cache.json
    
    # Verify cache cleared
    python -m tools.docs.cli cache-info
    # Output: Cache does not exist yet
    

  2. Force full rebuild:

    # Remove all generated content
    rm -rf docs/.build_cache.json docs/.index/
    
    # Rebuild everything
    python -m tools.docs.cli build-index
    make docs
    

  3. Check for corruption:

    # Validate cache JSON
    python -c "
    import json
    from pathlib import Path
    
    cache_path = Path('docs/.build_cache.json')
    try:
        data = json.loads(cache_path.read_text())
        print('Cache valid')
        print(f'Version: {data.get(\"cache_version\")}')
        print(f'Files: {len(data.get(\"files\", {}))}')
    except json.JSONDecodeError as e:
        print(f'Cache corrupted: {e}')
        print('Remove and rebuild')
    "
    

Problem: "IndexCorruptedError" when building index

Symptom:

tools.docs.core.cache.IndexCorruptedError: Build cache corrupted

Diagnosis: - Index file partially written - Disk full during write - Process killed during write

Resolution:

  1. Remove corrupted index:

    # Remove corrupted files
    rm docs/.index/cross_refs.json
    rm docs/.build_cache.json
    

  2. Rebuild from scratch:

    # Full index rebuild
    python -m tools.docs.cli build-index
    
    # Verify
    cat docs/.index/cross_refs.json | jq '.version'
    # Output: "2.1"
    

  3. Check disk space:

    # Ensure sufficient space
    df -h .
    
    # Clean up if needed
    make docs-clean
    docker system prune -f  # If using Docker
    

Problem: Cache grows too large

Symptom: - Cache file > 100MB - Slow cache operations - High memory usage

Diagnosis: - Too many tracked files - Large files cached - Cache not pruning old entries

Resolution:

  1. Check cache size:

    # Check file size
    ls -lh docs/.build_cache.json
    
    # Count tracked files
    python -c "
    import json
    from pathlib import Path
    
    cache = json.loads(Path('docs/.build_cache.json').read_text())
    print(f'Tracked files: {len(cache[\"files\"])}')
    print(f'Templates: {len(cache[\"templates\"])}')
    print(f'Config entries: {len(cache[\"config\"])}')
    "
    

  2. Clear and rebuild:

    # Clear cache
    python -m tools.docs.cli cache-clear
    
    # Rebuild (will only track current files)
    python -m tools.docs.cli build-index
    

  3. Add cache size limits:

    # In BuildCache class, add pruning:
    def prune_old_entries(self, max_files: int = 10000):
        """Remove oldest entries if cache too large."""
        if len(self.cache['files']) > max_files:
            # Sort by last accessed
            sorted_files = sorted(
                self.cache['files'].items(),
                key=lambda x: x[1].get('last_accessed', 0)
            )
            # Remove oldest
            for path, _ in sorted_files[:len(sorted_files) - max_files]:
                del self.cache['files'][path]
    

Git Hook Problems

Problem: Pre-commit hook blocks valid commits

Symptom:

.git/hooks/pre-commit: Line 42: "TODO detected in docs/architecture/adr/001.md"

Diagnosis: - "TODO/FIXME" in documentation - Broken internal link - Missing frontmatter fields

Resolution:

  1. Find and fix action items:

    # Find all action items in staged files
    git diff --cached --name-only | xargs grep -n "TODO"
    
    # Either:
    # 1. Resolve action item and commit
    # 2. Move action item to issue tracker
    # 3. Use --no-verify (emergency only)
    git commit --no-verify -m "WIP: incomplete work"
    

  2. Fix broken internal links:

    # Check for broken links in staged files
    git diff --cached --name-only | xargs grep -n "\](../.*\.md)"
    
    # Verify target files exist
    ls -la docs/architecture/001-hybrid-modular-ddd.md
    
    # Fix link path
    # WRONG: [DDD](../architecture/001-hybrid-modular-ddd.md)
    # CORRECT: [DDD](001-hybrid-modular-ddd.md)
    

  3. Add missing frontmatter:

    ---
    title: "Document Title"
    status: "Draft"
    date: 2026-01-06
    ---
    
    Content here...
    

Problem: Git hooks not executing

Symptom: - Commits succeed without validation - Post-merge hook doesn't run

Diagnosis: - Hooks not installed - Not executable - Skipped with --no-verify

Resolution:

  1. Verify hooks installed:

    # Check hooks exist
    ls -la .git/hooks/ | grep -E "(pre-commit|post-merge)"
    
    # Expected:
    # -rwxr-xr-x 1 user user ... pre-commit
    # -rwxr-xr-x 1 user user ... post-merge
    

  2. Make executable:

    chmod +x .git/hooks/pre-commit
    chmod +x .git/hooks/post-merge
    

  3. Reinstall hooks:

    # Force reinstall
    ./tools/hooks/install.sh --force
    
    # Verify
    ls -la .git/hooks/
    

  4. Test hooks:

    # Test pre-commit
    git add docs/
    .git/hooks/pre-commit
    
    # Test post-merge
    .git/hooks/post-merge
    

Problem: Post-merge hook fails after git pull

Symptom:

.git/hooks/post-merge: Line 15: python3: command not found

Diagnosis: - Python not in PATH - Wrong Python binary - Virtualenv not activated

Resolution:

  1. Set Python binary:

    # Use specific Python version
    export PYTHON_BIN=python3.12
    
    # Then pull (hook will use $PYTHON_BIN)
    git pull origin main
    

  2. Activate virtualenv (if using):

    # Activate before pull
    source .venv/bin/activate
    git pull origin main
    

  3. Skip hook temporarily:

    # Skip post-merge hook
    SKIP_POST_MERGE=1 git pull origin main
    

CI/CD Workflow Failures

Problem: Docs build fails in CI but works locally

Symptom: - CI pipeline fails at documentation build step - Same command succeeds locally

Diagnosis: - Missing dependencies in CI - Different Python version - Environment variables not set - File permissions issue

Resolution:

  1. Check CI dependencies:

    # In .github/workflows/docs.yml or similar
    - name: Install dependencies
      run: |
        pip install --upgrade pip
        pip install mkdocs-material mkdocstrings[python] mkdocs-section-index
        pip install -e backend/
    

  2. Verify Python version:

    - name: Set up Python
      uses: actions/setup-python@v4
      with:
        python-version: '3.12'  # Match local version
    

  3. Check environment variables:

    - name: Build documentation
      env:
        PYTHONPATH: ${{ github.workspace }}/backend
      run: |
        python -m tools.docs.cli build-index
        mkdocs build
    

  4. Compare environments:

    # Locally - capture environment
    python -m pip freeze > local-requirements.txt
    
    # In CI - capture environment
    pip freeze > ci-requirements.txt
    
    # Compare
    diff local-requirements.txt ci-requirements.txt
    

Problem: mkdocstrings fails in CI with module not found

Symptom:

ModuleNotFoundError: No module named 'app'

Diagnosis: - PYTHONPATH not set in CI - Backend not installed as package - Working directory different

Resolution:

  1. Set PYTHONPATH in CI:

    - name: Build docs
      run: |
        export PYTHONPATH=$GITHUB_WORKSPACE/backend:$PYTHONPATH
        mkdocs build
    

  2. Install backend package:

    - name: Install backend
      working-directory: ./backend
      run: |
        pip install --no-deps -c constraints.txt -e .
    

  3. Use absolute paths:

    # In mkdocs.yml
    plugins:
      - mkdocstrings:
          handlers:
            python:
              paths: [../backend]  # Relative to docs/ directory
    

Problem: Git hooks fail in CI

Symptom:

.husky/pre-commit: Permission denied

Diagnosis: - Hooks not executable in CI - Hooks not installed in CI environment - Different shell in CI

Resolution:

  1. Skip hooks in CI:

    # In CI workflow, set environment
    env:
      SKIP: pre-commit,post-merge
    

  2. Install hooks in CI:

    - name: Install git hooks
      run: |
        ./tools/hooks/install.sh
    

  3. Make hooks executable:

    # In install script, ensure:
    chmod +x .git/hooks/pre-commit
    chmod +x .git/hooks/post-merge
    

Performance Issues

Problem: Slow documentation builds

Symptom: - mkdocs build takes > 5 minutes - CLI commands hang

Diagnosis: - Large documentation set - No incremental builds - Expensive operations in hooks

Resolution:

  1. Use incremental builds:

    # Instead of full rebuild
    python -m tools.docs.cli build-index --incremental
    

  2. Disable expensive hooks:

    # Temporarily disable
    SKIP_POST_MERGE=1 git pull
    

  3. Optimize mkdocs configuration:

    # In mkdocs.yml
    plugins:
      - search:
          lang: en
          # Remove if not needed
          # separator: '[\s\-:,]+'
    

  4. Use build cache:

    # Check cache is working
    python -m tools.docs.cli cache-info
    
    # Clear if too large
    python -m tools.docs.cli cache-clear
    

Problem: Memory errors during build

Symptom:

MemoryError: Cannot allocate memory
or process killed with OOM

Diagnosis: - Large test files loaded entirely - Many documents in memory - Memory leak in generator

Resolution:

  1. Use streaming for large files:

    # In TestReportGenerator, large files use ijson
    if file_size > 10_000_000:  # 10MB
        import ijson
        # Stream instead of load all
    

  2. Limit concurrent operations:

    # Reduce parallelism
    export MKDOCS_MULTITHREAD=1
    mkdocs build
    

  3. Increase swap space:

    # Temporary workaround
    sudo fallocate -l 4G /swapfile
    sudo chmod 600 /swapfile
    sudo mkswap /swapfile
    sudo swapon /swapfile
    

Error Reference Table

Error Cause Resolution
Config value error Invalid mkdocs.yml Validate YAML, check plugin installation
Page not found Missing file or wrong path Verify file exists, update mkdocs.yml
Template not found Missing template file Recreate template in tools/docs/templates/
ModuleNotFoundError Module not in PYTHONPATH Set PYTHONPATH or install backend package
IndexCorruptedError Corrupted cache/index Delete .build_cache.json, rebuild
Permission denied Git hook not executable chmod +x .git/hooks/pre-commit
MemoryError Large file in memory Use streaming, reduce file size
ImportError Missing dependency pip install required packages
AttributeError Wrong module path Verify module structure and path
JSONDecodeError Corrupted JSON file Validate JSON, recreate from scratch

Getting Help

If problems persist:

  1. Check logs:

    # Enable verbose output
    python -m tools.docs.cli --verbose build-index
    
    # Check mkdocs logs
    mkdocs build --verbose
    

  2. Verify installation:

    # Check all dependencies
    pip list | grep -E "(mkdocs|mkdocstrings|jinja2|click|ijson|pyyaml)"
    
    # Expected versions:
    # mkdocs-material >= 9.5.0
    # mkdocstrings >= 0.24.0
    # mkdocs-section-index >= 0.3.0
    # ijson >= 3.3
    # PyYAML >= 6.0
    # jinja2 >= 3.1.2
    # click >= 8.1.0
    

  3. Reinstall from scratch:

    # Uninstall all
    pip uninstall mkdocs-material mkdocstrings mkdocs-section-index -y
    
    # Reinstall
    pip install --upgrade mkdocs-material mkdocstrings[python] mkdocs-section-index
    
    # Reinstall hooks
    ./tools/hooks/install.sh --force
    

  4. Check for updates:

    # Update to latest versions
    pip install --upgrade mkdocs-material mkdocstrings mkdocs-section-index
    

Sources