Troubleshooting Guide¶
Common issues and their solutions when working with Mooncake.
Installation Issues¶
"command not found: mooncake"¶
Problem: After installing with go install, the mooncake command is not found.
Solution: Ensure $GOPATH/bin (or $HOME/go/bin) is in your PATH:
# Add to ~/.bashrc, ~/.zshrc, or equivalent
export PATH="$PATH:$HOME/go/bin"
# Or find your GOPATH
go env GOPATH
# Verify
which mooncake
Permission denied when installing¶
Problem: go install fails with permission errors.
Solution: Don't use sudo with go install. Install to your user directory:
# Correct way
go install github.com/alehatsman/mooncake@latest
# Wrong way (don't do this)
sudo go install github.com/alehatsman/mooncake@latest
Configuration Errors¶
"invalid configuration: unknown field"¶
Problem: YAML contains a typo or invalid field name.
Solution: Check spelling of action names and fields. Common typos:
shel→shellcomand→commandtemplete→template
Use schema validation to catch these early:
"yaml: unmarshal errors"¶
Problem: Invalid YAML syntax.
Solution: Check YAML formatting:
- Proper indentation (use spaces, not tabs)
- Quoted strings containing special characters
- Proper list syntax
# Wrong
- name: Test
shell: echo "hello"
# Right
- name: Test
shell: echo "hello"
# Wrong - mixed indentation
- name: Test
shell: |
echo "line 1"
echo "line 2" # Too much indent
# Right
- name: Test
shell: |
echo "line 1"
echo "line 2"
Use a YAML validator:
"failed to expand template"¶
Problem: Template variable is undefined or template syntax is invalid.
Solution:
-
Define the variable before using it:
-
Use conditional to check if variable exists:
-
Check template syntax:
Execution Errors¶
"permission denied"¶
Problem: Trying to access a file or directory without sufficient permissions.
Solution: Use become: true for operations requiring root:
Then run with sudo password:
"sudo: no password provided"¶
Problem: Step requires sudo but no password method was specified.
Solution: Provide sudo password using one of these methods:
# Interactive prompt
mooncake run --config config.yml --ask-become-pass
mooncake run --config config.yml -K # shorthand
# Password file
echo "your_password" > ~/.mooncake/sudo_pass
chmod 600 ~/.mooncake/sudo_pass
mooncake run --config config.yml --sudo-pass-file ~/.mooncake/sudo_pass
# SSH askpass (for GUI environments)
export SUDO_ASKPASS=/usr/bin/ssh-askpass
mooncake run --config config.yml
"command not found"¶
Problem: Shell command doesn't exist on the system.
Solution:
-
Check if command is installed:
-
Use OS-specific commands:
"timeout: command took too long"¶
Problem: Command exceeds default 2-minute timeout.
Solution: Increase timeout:
File Operation Errors¶
"file already exists"¶
Problem: Trying to create file/directory that already exists.
Solution: This is usually fine - Mooncake operations are idempotent. If you see an error, check the state parameter:
# Creates or ensures file exists (idempotent)
- name: Ensure file exists
file:
path: /tmp/myfile
state: file
# Creates or ensures directory exists (idempotent)
- name: Ensure directory exists
file:
path: /tmp/mydir
state: directory
"no such file or directory"¶
Problem: Trying to operate on a file that doesn't exist, or parent directory doesn't exist.
Solution:
-
Create parent directories first:
-
Use
createsto make operation conditional:
"checksum mismatch"¶
Problem: Downloaded file checksum doesn't match expected value.
Solution:
- Verify the checksum value is correct
- Re-download the file (might be corrupted)
- Check if upstream changed the file
- name: Download with correct checksum
download:
url: https://example.com/file.tar.gz
dest: /tmp/file.tar.gz
checksum: sha256:abc123def456... # Verify this is correct
retries: 3 # Retry on failure
Get correct checksum:
Variable & Template Issues¶
"undefined variable"¶
Problem: Using a variable that hasn't been defined.
Solution:
-
Define variable before use:
-
Use system facts (automatically available):
-
Check variable scope - variables defined in one config file aren't available in included files unless passed explicitly.
"template rendering failed"¶
Problem: Invalid Jinja2 template syntax.
Solution: Check template syntax:
# Wrong - spaces in variable name
{{ my var }}
# Right
{{ my_var }}
# Wrong - missing endif
{% if condition %}
something
# Right
{% if condition %}
something
{% endif %}
# Wrong - invalid filter
{{ value | badfilter }}
# Right - use valid filters
{{ path | expanduser }}
{{ text | upper }}
{{ file | basename }}
Platform-Specific Issues¶
macOS: "operation not permitted"¶
Problem: macOS security restrictions prevent file operations.
Solution:
- Grant Full Disk Access to Terminal:
- System Settings → Privacy & Security → Full Disk Access
-
Add Terminal.app or iTerm.app
-
Use
become: truefor system modifications
Linux: "systemd service not found"¶
Problem: Trying to manage a service that doesn't exist.
Solution:
-
Verify service name:
-
Create service first, then manage it:
- name: Create systemd unit service: name: myapp unit: dest: /etc/systemd/system/myapp.service content: | [Unit] Description=My App [Service] ExecStart=/usr/local/bin/myapp [Install] WantedBy=multi-user.target daemon_reload: true become: true - name: Start service service: name: myapp state: started enabled: true become: true
Windows: "command not supported"¶
Problem: Some actions work differently on Windows.
Solution: Use platform-specific conditionals:
- name: Unix command
shell: ls -la
when: os != "windows"
- name: Windows command
shell: dir
when: os == "windows"
Preset Issues¶
"preset not found"¶
Problem: Trying to use a preset that doesn't exist.
Solution:
-
List available presets:
-
Check preset name spelling:
-
Verify preset is installed (if using custom presets)
"invalid preset parameters"¶
Problem: Preset parameters don't match schema.
Solution: Check preset documentation:
Use correct parameter names and types:
# Wrong - state is string, not boolean
- preset: docker
with:
state: true
# Right
- preset: docker
with:
state: present
"preset failed during execution"¶
Problem: Preset step failed.
Solution:
-
Run with debug logging:
-
Check preset source code:
-
Try manual installation to isolate issue
Performance Issues¶
"execution is very slow"¶
Problem: Configuration takes a long time to run.
Solution:
-
Use dry-run to identify slow steps:
-
Reduce retries and timeouts where not needed:
-
Use tags to run only necessary steps:
-
Check for unnecessary loops:
Debugging Techniques¶
Enable debug logging¶
Use dry-run mode¶
Generate execution plan¶
# See the execution plan
mooncake plan --config config.yml
# Export as JSON for analysis
mooncake plan --config config.yml --format json --output plan.json
Test individual steps¶
Use tags to isolate problematic steps:
Check system facts¶
# View all detected system information
mooncake facts
# Export as JSON
mooncake facts --format json > facts.json
Register and inspect results¶
- name: Run command
shell: my-command.sh
register: result
- name: Show result
shell: echo "RC={{result.rc}} STDOUT={{result.stdout}}"
Use ignore_errors¶
- name: Optional step
shell: might-fail.sh
register: result
ignore_errors: true
- name: Check if failed
shell: echo "Previous step failed"
when: result.rc != 0
Getting Help¶
Check documentation¶
Validate configuration¶
Report bugs¶
If you've found a bug:
-
Create minimal reproduction:
-
Include system information:
-
Report at GitHub Issues
Common Patterns¶
Safe file operations¶
# Always create parent directories first
- name: Create config directory
file:
path: ~/.config/myapp
state: directory
# Then create files
- name: Create config
file:
path: ~/.config/myapp/config.yml
state: file
content: "..."
Idempotent commands¶
# Use creates/removes for idempotency
- name: Extract tarball
shell: tar xzf /tmp/app.tar.gz -C /opt
args:
creates: /opt/app/bin/app # Only if doesn't exist
- name: Clean up
shell: rm -rf /tmp/cache
args:
removes: /tmp/cache # Only if exists
Error handling¶
- name: Try to download
download:
url: https://example.com/file.tar.gz
dest: /tmp/file.tar.gz
register: download_result
ignore_errors: true
- name: Use fallback if download failed
download:
url: https://mirror.example.com/file.tar.gz
dest: /tmp/file.tar.gz
when: download_result.rc != 0
See Also¶
- Quick Reference - Common commands and patterns
- FAQ - Frequently asked questions
- Examples - Working examples
- GitHub Issues - Report bugs