Debugging Omarchy CLI Routing Issues: Route Collisions and Missing Commands
To debug Omarchy CLI routing issues, inspect the associative arrays built in bin/omarchy—particularly checking ROUTE_COLLISIONS for duplicate registrations and verifying that executable binaries follow the omarchy-<group> naming pattern in the bin/ directory.
The Omarchy CLI uses a thin router that maps textual routes (the arguments following omarchy) to executable binaries. Understanding how the router constructs its lookup tables and detects conflicts is essential for troubleshooting both route collisions and missing command errors in the omacom/omarchy repository.
How the Omarchy CLI Router Works
The router script located at bin/omarchy initializes several associative arrays during startup to manage command resolution:
COMMAND_ROUTE: Maps primary routes to command keysCOMMAND_FALLBACK_ROUTE: Stores fallback routes for hidden groupsROUTE_TO_KEY: Provides direct lookup from route string to keyROUTE_IS_ALIAS: Flags routes declared as aliasesROUTE_COLLISIONS: Collects duplicate route definitions for error reporting
Command Registration and Collision Detection
The register_command function scans each omarchy-* binary in the bin/ directory, extracting metadata from header comments to populate the routing arrays. During registration, the router strictly checks for duplicate routes:
if [[ -n ${ROUTE_TO_KEY[$route]} && ${ROUTE_TO_KEY[$route]} != "$key" ]]; then
ROUTE_COLLISIONS+=("$route -> ${ROUTE_TO_KEY[$route]} conflicts with $key")
fi
This collision detection logic appears at lines 58–61 of bin/omarchy. If the ROUTE_TO_KEY array already contains an entry for a route that differs from the current command key, the router appends a collision warning to the ROUTE_COLLISIONS array and will abort after scanning all binaries.
Route Resolution Logic
When executing a command, the router attempts resolution through two distinct phases. First, resolve_direct_route attempts to match the longest possible prefix of user arguments to an existing binary by walking the argument list backwards:
route="omarchy $(join_words " " "${args[@]:0:prefix_count}")"
binary="omarchy-$(join_words "-" "${args[@]:0:prefix_count}")"
This logic, found at lines 99–107 of bin/omarchy, constructs candidate binary names like omarchy-update-aur from route fragments. If no direct match exists, the system falls back to resolve_route, which consults the fallback map used for hidden groups while preserving alias handling and --help flag support.
Common Omarchy CLI Routing Failure Patterns
Route Collisions
Route collisions occur when two separate binaries define identical primary routes. For example, if both an official omarchy-update binary and a custom script named omarchy-update exist in bin/, the router detects the conflict during the registration phase:
omarchy: route collision: omarchy update -> omarchy-update conflicts with my-custom-update
The router populates ROUTE_COLLISIONS with descriptive conflict messages and exits with a non-zero status, preventing ambiguous command execution.
Missing Commands
When users invoke non-existent routes such as omarchy foo bar, the resolution functions fail to locate matching binaries. The trace reveals resolve_direct_route attempting progressively shorter prefixes:
omarchy-foo-bar(not found)omarchy-foo(not found)
After exhausting all possibilities and checking fallback routes, the router emits:
omarchy: unknown command 'foo bar'
This behavior is deterministic—the router never guesses but strictly relies on the maps built from files present in bin/.
Step-by-Step Debugging Process
Follow these systematic steps to diagnose routing issues:
-
Enable verbose tracing by adding
set -xto the top ofbin/omarchyor invokingbash -x bin/omarchy <command>. This reveals eachregister_commandcall and collision detection check. -
Inspect collision arrays after a failed startup by running
printf '%s\n' "${ROUTE_COLLISIONS[@]}"to view any duplicate route registrations. -
List registered routes using
declare -p COMMAND_ROUTEafter the script loads to verify what the router recognizes as available commands. -
Verify binary naming and permissions. The executable must reside directly under
bin/with the exact patternomarchy-<group>(underscores become hyphens) and have executable permissions viachmod +x. -
Re-run the failing command after corrections to confirm the router successfully resolves the direct route.
Fixing Route Collisions: A Practical Example
When two binaries compete for the same route, rename the conflicting custom script:
# Identify the collision via error message or trace
mv bin/omarchy-update bin/omarchy-update-custom
chmod +x bin/omarchy-update-custom
# Verify resolution
omarchy update # Now resolves to official update command
omarchy update-custom # Resolves to your custom script
Diagnosing Missing Commands with Trace Mode
To understand why a specific command fails to resolve, enable execution tracing:
set -x
omarchy foo bar
The trace output shows the iteration logic in resolve_direct_route testing candidate binaries:
+ route='omarchy foo bar'
+ binary='omarchy-foo-bar'
+ [[ -x bin/omarchy-foo-bar ]]
+ route='omarchy foo'
+ binary='omarchy-foo'
+ [[ -x bin/omarchy-foo ]]
This reveals exactly which binary names the router expects based on your input arguments.
Key Source Files for Router Debugging
Understanding these files helps isolate routing problems:
bin/omarchy: The main router script containingregister_command,resolve_direct_route, and collision detection logicbin/omarchy-*: Individual command binaries providing metadata parsed during registrationtest/shell.d/menu-test.sh: Test suite validating route resolution behavior, including exact-match priority over fuzzy matches (see lines 165–166)agents/skills/command-metadata.md: Documentation of the metadata comment format required by each binary
The test suite specifically verifies that exact-match routes win over fuzzy matches, as demonstrated in test/shell.d/menu-test.sh where menu routes cannot be hijacked by installed application keywords.
Summary
- Collision detection occurs during startup in
register_command(lines 58–61 ofbin/omarchy), populatingROUTE_COLLISIONSwhen duplicate routes are detected - Route resolution uses
resolve_direct_route(lines 99–107) to match user input againstomarchy-<group>binaries by walking argument prefixes backwards - Binary naming must follow the exact pattern
omarchy-<group>with hyphens replacing underscores, and files must be executable - Debugging tools include
set -xtracing, inspectingROUTE_COLLISIONS, and usingdeclare -pon routing arrays - Fallback routes support hidden groups but still require proper binary existence and metadata
Frequently Asked Questions
What causes route collisions in Omarchy?
Route collisions occur when two binaries in the bin/ directory define identical primary routes in their metadata headers. The register_command function detects these duplicates at lines 58–61 of bin/omarchy by checking if ROUTE_TO_KEY[$route] already exists and differs from the current command key. The router aborts startup and prints collision details to prevent ambiguous command execution.
How does Omarchy resolve ambiguous command routes?
Omarchy resolves routes through a deterministic two-phase process. First, resolve_direct_route attempts exact prefix matching by constructing candidate binary names like omarchy-foo-bar from user arguments. If this fails, the system falls back to resolve_route, which checks hidden group mappings and aliases. The router never guesses—it either finds an exact binary match or returns an "unknown command" error.
Where are command routes registered in the Omarchy source?
Command routes are registered in bin/omarchy within the register_command function. This function scans all omarchy-* executables in bin/ during shell initialization, extracting metadata from comment headers to populate associative arrays including COMMAND_ROUTE, ROUTE_TO_KEY, and ROUTE_COLLISIONS. The registration happens before any user command execution, ensuring the routing table is fully constructed upfront.
Why does my custom Omarchy script not appear as a command?
Custom scripts fail to appear when they violate the naming convention or lack executable permissions. The router only recognizes files matching omarchy-<group> directly under bin/, where underscores in group names become hyphens. Additionally, the file must be executable (chmod +x) and contain valid metadata headers. If named incorrectly, the script may only appear in fallback maps or remain invisible to the router entirely.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →