Skip to content

Troubleshooting Guide

Common issues and their solutions when using plowman.

Installation Issues

Command Not Found

Problem: After installation, plm command is not found.

$ plm --version
command not found: plm

Solutions:

If installed with uv:

# Check if uv's bin directory is in PATH
$ which plm

# Add to shell config (~/.bashrc or ~/.zshrc)
export PATH="$HOME/.local/bin:$PATH"

# Reload shell
$ source ~/.bashrc

If installed with pip:

# Check Python's bin directory
$ python3 -m site --user-base
/home/user/.local

# Add to PATH
export PATH="$HOME/.local/bin:$PATH"

# Or use virtual environment
$ source ~/.venvs/plowman/bin/activate

Verify installation:

$ which plm
/home/user/.local/bin/plm

$ plm --version
plowman 0.3.1

Permission Errors

Problem: Permission denied when installing with pip.

$ pip install plowman
PermissionError: [Errno 13] Permission denied: '/usr/lib/python3.10'

Solutions:

Use --user flag:

$ pip install --user plowman

Use virtual environment (recommended):

$ python3 -m venv ~/.venvs/plowman
$ source ~/.venvs/plowman/bin/activate
$ pip install plowman

Use uv (best option):

$ uv tool install plowman

uv handles isolation automatically and doesn't require sudo.

Python Version Issues

Problem: Error about Python version requirements.

ERROR: Package 'plowman' requires a different Python: 3.9.0 not in '>=3.10'

Solutions:

Check current Python version:

$ python3 --version
Python 3.9.0

Install newer Python:

On macOS with Homebrew:

$ brew install python@3.14

On Ubuntu/Debian:

$ sudo add-apt-repository ppa:deadsnakes/ppa
$ sudo apt update
$ sudo apt install python3.14

Using pyenv:

$ pyenv install 3.14.0
$ pyenv global 3.14.0

Then reinstall plowman:

$ pip uninstall plowman
$ pip install plowman

Configuration Issues

MissingConfigError

Problem: Configuration file not found.

plowman.lib.exceptions.MissingConfigError: Configuration file not found at ~/.config/plowman/config.yaml

Solution:

Create the configuration file:

$ mkdir -p ~/.config/plowman
$ cat > ~/.config/plowman/config.yaml << 'EOF'
estates:
  ~/dotfiles:
    granaries: ["bash"]
EOF

Verify it exists:

$ ls -la ~/.config/plowman/config.yaml
-rw-r--r-- 1 user user 50 Jun 24 10:00 /home/user/.config/plowman/config.yaml

MissingGranaryError

Problem: Granary directory doesn't exist.

plowman.lib.exceptions.MissingGranaryError: Granary path does not exist: /home/user/dotfiles/bash

Solutions:

Check the path:

$ ls ~/dotfiles/bash
ls: cannot access '/home/user/dotfiles/bash': No such file or directory

Create the directory:

$ mkdir -p ~/dotfiles/bash

Fix typo in config:

# Wrong
estates:
    ~/dotfiles:
        granaries: ["bsh"] # Typo!

# Correct
estates:
    ~/dotfiles:
        granaries: ["bash"]

Use absolute paths:

# Better
estates:
    /home/user/dotfiles:
        granaries: ["bash"]

Invalid YAML Syntax

Problem: YAML parsing errors.

yaml.scanner.ScannerError: mapping values are not allowed here

Solutions:

Validate YAML syntax:

$ python3 -c "import yaml; yaml.safe_load(open('~/.config/plowman/config.yaml'))"

Common issues:

Tabs instead of spaces:

# Wrong (uses tabs)
estates:
→~/dotfiles:
→→granaries: ["bash"]

# Correct (uses spaces)
estates:
    ~/dotfiles:
        granaries: ["bash"]

Missing quotes for special characters:

# Wrong
variables:
    email: user@example.com

# Correct
variables:
    email: "user@example.com"

Incorrect indentation:

# Wrong
estates:
~/dotfiles:
granaries: ["bash"]

# Correct
estates:
    ~/dotfiles:
        granaries: ["bash"]

Template Issues

Undefined Variable Error

Problem: Jinja2 can't find a variable.

jinja2.exceptions.UndefinedError: 'username' is undefined

Solutions:

Add variable to config:

estates:
    ~/dotfiles:
        granaries: ["bash"]
        variables:
            username: alice # Add this

Check template syntax:

# Wrong
{{ usernmae }}  # Typo!

# Correct
{{ username }}

Use default filter:

{{ username | default("anonymous") }}

Debug with verbose mode:

$ plm sow --dry-run -vvv

Template Syntax Error

Problem: Jinja2 syntax error in template.

jinja2.exceptions.TemplateSyntaxError: unexpected char '%' at position 10

Solutions:

Check for typos:

# Wrong
{% if os == "linux" %
{% endif %}

# Correct
{% if os == "linux" %}
{% endif %}

Balance blocks:

# Wrong
{% if condition %}
content
# Missing endif

# Correct
{% if condition %}
content
{% endif %}

Escape literal braces:

# If you need literal {{ in output
{% raw %}
{{ this won't be processed }}
{% endraw %}

Template Not Being Rendered

Problem: Template file is copied as-is without variable substitution.

Solutions:

Mark file as template:

# ~/dotfiles/.plowman/plowman.yml
bash:
    templates:
        - .bashrc.j2 # Must be listed here

Check file extension: Template files commonly use .j2 extension, but any extension works as long as it's listed in the templates config.

Verify template is in correct granary:

$ ls ~/dotfiles/bash/.bashrc.j2
/home/user/dotfiles/bash/.bashrc.j2

# Check config matches
$ cat ~/dotfiles/.plowman/plowman.yml
bash:
  templates:
    - .bashrc.j2

Deployment Issues

Files Not Being Deployed

Problem: Expected files are not deployed to home directory.

Solutions:

Check granary configuration:

estates:
    ~/dotfiles:
        granaries:
            - bash # Is this listed?
            - nvim

Verify files exist in granary:

$ ls ~/dotfiles/bash/
.bashrc
.bash_profile

Run with verbose output:

$ plm sow -v
☑️ Copying /home/user/dotfiles/bash/.bashrc to /home/user/.bashrc

Check for hash match (file unchanged): If the file hasn't changed since last deployment, plowman skips it. Force re-deployment:

$ touch ~/dotfiles/bash/.bashrc
$ plm sow -v

Files Being Deleted Unexpectedly

Problem: Files are removed that you didn't expect.

Cause: Files tracked in estate but no longer in configuration are considered orphaned and deleted.

Solutions:

Preview deletions first:

$ plm sow --dry-run -v
🧹 Would delete /home/user/.old_config

Add file back to configuration:

estates:
    ~/dotfiles:
        granaries:
            - bash
            - old_config # Re-add this

Reset estate if needed:

$ rm ~/dotfiles/.plowman/estate.yml
$ plm sow

Permission Denied on Write

Problem: Can't write to destination.

PermissionError: [Errno 13] Permission denied: '/home/user/.bashrc'

Solutions:

Check file permissions:

$ ls -la ~/.bashrc
-rw------- 1 root root 123 Jun 24 10:00 /home/user/.bashrc

Fix ownership:

$ sudo chown $USER:$USER ~/.bashrc

Or run as correct user: Don't use sudo with plowman. It should run as your user.

Estate Issues

Estate File Corruption

Problem: Estate file is malformed or causes errors.

yaml.parser.ParserError: while parsing a block mapping

Solution:

Delete and rebuild:

$ rm ~/dotfiles/.plowman/estate.yml
$ plm sow

This creates a fresh estate file from scratch.

Estate Out of Sync

Problem: Estate doesn't match actual deployed files.

Symptoms:

  • Files being deleted that shouldn't be
  • Files not being cleaned up that should be

Solution:

Reset estate:

$ rm ~/dotfiles/.plowman/estate.yml
$ plm sow -v

Verify all expected files are deployed:

$ cat ~/dotfiles/.plowman/estate.yml

Performance Issues

Slow Deployment

Problem: plowman takes a long time to deploy.

Causes and Solutions:

Many files: plowman processes files sequentially. For hundreds of files, this may take time.

Network filesystems: If granaries are on NFS or similar, file operations are slower.

Solution - Use hashing efficiently: plowman already skips unchanged files via SHA256 hashing. Ensure you're not forcing re-deployment unnecessarily.

Debug slow runs:

$ time plm sow -v

High Memory Usage

Problem: plowman uses more memory than expected.

Note: This is unlikely as plowman is designed to be lightweight. If you experience this:

Check for very large files: Templates are loaded into memory for rendering.

Solution: Split large configurations into multiple smaller granaries.

Debugging Tips

Enable Maximum Verbosity

For detailed debugging output:

$ plm sow -vvv

This shows:

  • All files being processed
  • Full diffs for changes
  • Complete tracebacks on errors

Use Dry-Run for Safe Testing

Always test changes with dry-run first:

$ plm sow --dry-run -vv

This shows what would happen without making changes.

Check Configuration Files

Validate your configuration:

# Main config
$ cat ~/.config/plowman/config.yaml

# Per-path config
$ cat ~/dotfiles/.plowman/plowman.yml

# Estate file
$ cat ~/dotfiles/.plowman/estate.yml

Verify File Paths

Ensure paths are correct:

# Check granary exists
$ ls ~/dotfiles/bash/

# Check config path
$ ls ~/.config/plowman/config.yaml

# Check template markers
$ ls ~/dotfiles/.plowman/plowman.yml

Test Template Rendering

Test a template manually:

$ python3 << 'EOF'
from jinja2 import Template

template = Template(open("~/dotfiles/bash/.bashrc.j2").read())
result = template.render(username="alice", hostname="workstation")
print(result)
EOF

Getting Help

If you're still stuck:

  1. Check the docs:

  2. Search existing issues: GitHub Issues

  3. Open a new issue: Include:

    • plowman version: plm --version
    • Error message (full traceback with -vvv)
    • Relevant config snippets
    • What you expected vs what happened
  4. Community: Check if there's a community forum or chat for plowman users.