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 keys
  • COMMAND_FALLBACK_ROUTE: Stores fallback routes for hidden groups
  • ROUTE_TO_KEY: Provides direct lookup from route string to key
  • ROUTE_IS_ALIAS: Flags routes declared as aliases
  • ROUTE_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:

  1. Enable verbose tracing by adding set -x to the top of bin/omarchy or invoking bash -x bin/omarchy <command>. This reveals each register_command call and collision detection check.

  2. Inspect collision arrays after a failed startup by running printf '%s\n' "${ROUTE_COLLISIONS[@]}" to view any duplicate route registrations.

  3. List registered routes using declare -p COMMAND_ROUTE after the script loads to verify what the router recognizes as available commands.

  4. Verify binary naming and permissions. The executable must reside directly under bin/ with the exact pattern omarchy-<group> (underscores become hyphens) and have executable permissions via chmod +x.

  5. 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 containing register_command, resolve_direct_route, and collision detection logic
  • bin/omarchy-*: Individual command binaries providing metadata parsed during registration
  • test/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 of bin/omarchy), populating ROUTE_COLLISIONS when duplicate routes are detected
  • Route resolution uses resolve_direct_route (lines 99–107) to match user input against omarchy-<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 -x tracing, inspecting ROUTE_COLLISIONS, and using declare -p on 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →