Troubleshooting
This guide covers common issues you might encounter when using Hexagon and how to resolve them.
Installation Issues
Command not found after installation
Problem: After running hexagon and installing your CLI, the command is not found.
Solutions:
-
Restart your terminal - The shell needs to reload PATH
# Close and reopen your terminal, or:
source ~/.bashrc # or ~/.zshrc -
Check installation location
which hexagon
# Should show the hexagon installation path -
Verify Python/pipx installation
pip show hexagon
# or
pipx list | grep hexagon
Permission denied when installing
Problem: PermissionError when trying to install Hexagon or a CLI.
Solutions:
-
Use pipx instead of pip (recommended)
pipx install hexagon -
Use user installation with pip
pip install --user hexagon -
Use virtual environment
python -m venv venv
source venv/bin/activate
pip install hexagon
Configuration Issues
YAML parsing errors
Problem: YAML parse error or Invalid configuration messages.
Solutions:
-
Check YAML syntax
- Ensure proper indentation (use spaces, not tabs)
- Verify colons have spaces after them:
name: value - Check for special characters that need quoting
-
Validate with JSON schema
hexagon get-json-schema > schema.json
# Use IDE validation or online YAML validators -
Common YAML mistakes:
# Wrong - no space after colon
name:value
# Correct
name: value
# Wrong - tabs instead of spaces
→tools:
# Correct - use spaces
tools:
Config file not found
Problem: Configuration file not found error.
Solutions:
-
Check file name - Hexagon looks for
app.yamlorapp.yml -
Set HEXAGON_CONFIG_FILE environment variable
export HEXAGON_CONFIG_FILE=/path/to/your/config.yaml
mycli -
Check current directory
ls -la | grep app.yaml
# Config file should be in the current directory
Action Execution Issues
Tool not found / Action not found
Problem: Tool not found or ModuleNotFoundError when executing a tool.
Solutions:
-
For Python modules:
cli:
custom_tools_dir: ./custom_tools # Ensure this is set
tools:
- name: my-tool
action: my_module # Should be in custom_tools/my_module.py -
For script files:
tools:
- name: deploy
action: ./scripts/deploy.sh # Path relative to config file -
Check file exists
ls -la scripts/deploy.sh
# Verify file exists at the path specified -
Debug action resolution:
- Add print statements to see what's being executed
- Check if it's a script, module, or inline command
- See Action Execution for resolution order
Module import errors
Problem: ModuleNotFoundError or ImportError for custom Python tools.
Solutions:
-
Verify custom_tools_dir is set:
cli:
custom_tools_dir: ./custom_tools -
Check module structure:
custom_tools/
├── __init__.py # Not required but good practice
└── my_tool.py # Your tool module -
Ensure main() function exists:
# custom_tools/my_tool.py
def main(tool, env, env_args, cli_args):
# Your code here
pass -
Check Python path:
import sys
print(sys.path) # custom_tools_dir should be in this list
Script permission denied
Problem: Permission denied when executing a script.
Solutions:
-
Make script executable:
chmod +x scripts/deploy.sh -
Check shebang line:
#!/bin/bash
# Should be the first line of your script -
Verify script path:
ls -la scripts/deploy.sh
# Should show -rwxr-xr-x (executable permissions)
Environment Issues
Environment not working / env_args is None
Problem: Environment-specific values aren't being used.
Solutions:
-
Check environment name matches exactly:
envs:
- name: development # Must match exactly
tools:
- name: deploy
envs:
development: value # Same name -
Use wildcard for all environments:
tools:
- name: open-docs
envs:
"*": https://docs.example.com -
Check if tool requires environment:
- If no
envsin tool definition, no environment selection happens - Use
envsonly when you need environment-specific values
- If no
Wrong environment selected
Problem: Hexagon selects the wrong environment or doesn't prompt.
Solutions:
-
Explicitly specify environment:
mycli deploy production # Specify environment name -
Check environment aliases:
envs:
- name: production
alias: prod # Can use "prod" instead -
Verify tool has envs defined:
tools:
- name: deploy
envs: # Without this, no environment selection
dev: config-dev
prod: config-prod
Plugin Issues
Plugin not loading
Problem: Plugin code doesn't execute or errors occur.
Solutions:
-
Verify plugin path:
cli:
plugins:
- plugins/my_plugin.py # Path relative to config file -
Check main() function:
# plugins/my_plugin.py
def main(): # Must be named 'main', takes no parameters
print("Plugin loaded!") -
Check for Python errors:
- Syntax errors in plugin file
- Import errors
- Exception during initialization
-
Debug plugin loading:
def main():
print("Plugin main() called") # Should see this when CLI starts
# Rest of plugin code
Hook not firing
Problem: Registered hooks don't execute.
Solutions:
-
Verify hook subscription:
from hexagon.support.hooks import HexagonHooks
from hexagon.support.hooks.hook import HookSubscription
def main():
HexagonHooks.start.subscribe(
HookSubscription("my-hook", callback=my_function)
) -
Check callback signature:
# Hooks with data
def on_tool_selected(selection): # Takes data parameter
print(f"Tool: {selection.value.name}")
# Hooks without data
def on_start(): # No parameters
print("Starting") -
Ensure plugin main() is called:
- Plugin must be loaded
- main() must execute without errors
Argument Issues
Arguments not prompting
Problem: Tool doesn't prompt for arguments.
Solutions:
-
Check Args class exists:
from hexagon.support.input.args import ToolArgs, PositionalArg, Arg
class Args(ToolArgs):
name: PositionalArg[str] = Arg(None, prompt_message="Enter name") -
Verify prompt logic:
def main(tool, env, env_args, cli_args: Args):
if not cli_args.name.value:
cli_args.name.prompt() # Must explicitly call prompt() -
Check default values:
# Won't prompt if default is not None
name: OptionalArg[str] = Arg("default", prompt_message="Name")
# Will prompt if value is None
name: PositionalArg[str] = Arg(None, prompt_message="Name")
Argument validation errors
Problem: ValidationError when passing arguments.
Solutions:
-
Check argument type:
age: PositionalArg[int] = Arg(None) # Expects integer
# mycli tool "not-a-number" # Will fail
# mycli tool 25 # Will work -
Use proper format:
mycli tool arg1 arg2 # Positional args
mycli tool --flag value # Optional args
mycli tool --flag=value # Alternative format -
Add validation:
from pydantic import validator
class Args(ToolArgs):
email: PositionalArg[str] = Arg(None)
@validator("email")
def validate_email(cls, v):
if "@" not in v:
raise ValueError("Must be a valid email")
return v
Performance Issues
Slow CLI startup
Problem: CLI takes a long time to start.
Solutions:
-
Reduce plugin count - Each plugin adds startup time
-
Lazy load heavy imports:
def main(tool, env, env_args, cli_args):
# Import heavy modules only when needed
import heavy_module
# Use module -
Disable update checks temporarily:
cli:
options:
update_disabled: true
cli_update_disabled: true -
Profile startup:
time mycli # Measure startup time
Slow tool execution
Problem: Tool takes a long time to execute.
Solutions:
-
Profile your code:
import time
start = time.time()
# Your code
print(f"Took {time.time() - start:.2f}s") -
Use background hooks for non-critical tasks:
from hexagon.support.hooks.hook import HookSubscrptionType
HexagonHooks.tool_executed.subscribe(
HookSubscription(
"telemetry",
callback=send_telemetry,
type=HookSubscrptionType.background # Don't block
)
) -
Optimize scripts:
- Remove unnecessary operations
- Cache expensive computations
- Use parallel execution where possible
Debugging Tips
Enable verbose output
# Run Hexagon with Python's verbose mode
python -v -m hexagon
# Or with debugging
python -m pdb -m hexagon
Check logs
# Add logging to your tools
import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
def main(tool, env, env_args, cli_args):
logger.debug(f"Tool: {tool.name}")
logger.debug(f"Env: {env}")
logger.debug(f"Args: {cli_args}")
Inspect configuration
# In a plugin or tool
from hexagon.runtime.singletons import cli, tools, envs
def main():
print("CLI:", cli.name)
print("Tools:", [t.name for t in tools])
print("Envs:", [e.name for e in envs])
Test tools in isolation
# Test a tool function directly
from custom_tools import my_tool
# Call main() directly
my_tool.main(tool=None, env=None, env_args=None, cli_args=None)
Getting Help
If you're still stuck:
- Check GitHub Issues: https://github.com/lt-mayonesa/hexagon/issues
- Read the docs: Start with Getting Started
- Review examples: Check the hexagon-tools template
- Ask for help: Open a new issue with:
- Hexagon version (
hexagon --version) - Your configuration file (sanitized)
- Error messages (full stack trace)
- Steps to reproduce
- Hexagon version (