How Nested Herdr Detection Is Implemented: Environment Variables and Configuration
Nested Herdr detection relies on an environment variable (HERDR_ENV=1) injected into every spawned pane and validated at startup against the experimental allow_nested configuration flag to prevent recursive UI sessions by default.
The ogulcancelik/herdr repository implements nested Herdr detection using a lightweight inheritance-based mechanism to identify when a new instance launches inside an existing Herdr-managed pane. This approach prevents confusing recursive terminal sessions while allowing power users to opt-in via explicit configuration settings.
Environment Variable Injection in Pane Spawning
Herdr marks every pane it creates by setting a specific environment variable that propagates to all child processes. In src/pane.rs, both the spawn_with_initial_history and spawn_shell_command functions build a CommandBuilder that explicitly injects the marker before launching the shell or command:
cmd.env(crate::HERDR_ENV_VAR, crate::HERDR_ENV_VALUE);
This corresponds to lines 77-78 in src/pane.rs, where HERDR_ENV_VAR and HERDR_ENV_VALUE resolve to HERDR_ENV and 1 respectively. Because environment variables automatically inherit through subprocesses, any command—including a new Herdr binary—launched from within that pane will carry HERDR_ENV=1 in its environment.
Detection Logic at Startup
When Herdr initializes, it immediately checks for the presence of this inherited marker to determine if it is running inside an existing Herdr session.
The should_block_nested_for_env Check
The core validation occurs in src/main.rs within the should_block_nested_for_env function (lines 79-81). This helper checks two conditions simultaneously:
- The
HERDR_ENVenvironment variable is set to the magic value1. - The
allow_nestedconfiguration flag isfalse(the default setting).
If both conditions evaluate to true, the function returns true, signaling that the current launch should be blocked to prevent nesting.
Consistency in Self-Updates
The same environment variable check is reused in src/update.rs during Herdr’s self-update process. This ensures that update operations maintain consistency with the nested detection logic and do not inadvertently spawn recursive instances during version upgrades.
Configuration Override and Blocking Behavior
Users who require nested Herdr sessions can bypass the default protection through an experimental configuration toggle.
The allow_nested Experimental Flag
In src/config/model.rs (lines 339-340), the configuration struct defines:
pub allow_nested: bool,
When users set allow_nested = true under the [experimental] section of herdr.toml, the should_block_nested_for_env check returns false regardless of the environment variable’s presence. This permits the nested instance to initialize normally.
Process Termination with exit_if_nested_disabled
If nesting is detected and the configuration flag remains false, src/main.rs invokes exit_if_nested_disabled (lines 94-100). This function prints a clear error message explaining that nested Herdr is disabled by default, selects a random quip from the NESTED_HERDR_MESSAGES array (defined in lines 12-18), and terminates the process with exit status 1.
Practical Usage Examples
Attempting to launch Herdr inside an existing Herdr pane without configuration changes results in immediate termination:
# Inside a Herdr-managed pane
$ herdr server
error: nested herdr is disabled by default.
see configuration if you want to enable it.
"inception detected. we need to go deeper... said no one ever."
To enable nested sessions, create or modify your herdr.toml configuration file:
[experimental]
allow_nested = true
After reloading the configuration, the same command will succeed because should_block_nested_for_env no longer triggers the exit handler.
Summary
- Environment marking:
src/pane.rssetsHERDR_ENV=1on every spawned pane, creating an inheritance chain that identifies Herdr-managed contexts. - Dual-condition check:
src/main.rsusesshould_block_nested_for_envto verify both the environment variable and theallow_nestedconfig flag before proceeding. - Graceful blocking:
exit_if_nested_disabledterminates prohibited nested launches with a helpful error and a random message fromNESTED_HERDR_MESSAGES. - User override: The
allow_nestedboolean insrc/config/model.rsprovides an opt-in mechanism for power users who need recursive terminal sessions. - Update consistency:
src/update.rsreuses the same detection logic to ensure self-update operations respect nesting constraints.
Frequently Asked Questions
How does Herdr detect if it is running inside another Herdr instance?
Herdr checks for the HERDR_ENV environment variable at program startup in src/main.rs. This variable is set to 1 by the CommandBuilder in src/pane.rs (lines 77-78) whenever Herdr spawns a new pane. If the variable is present and the allow_nested configuration flag is false, Herdr recognizes itself as nested and invokes exit_if_nested_disabled to prevent initialization.
Can I disable nested Herdr detection to run recursive sessions?
Yes. Set allow_nested = true under the [experimental] section in your herdr.toml configuration file. According to the source in src/config/model.rs (lines 339-340), this boolean changes the behavior of should_block_nested_for_env in src/main.rs to permit the nested instance to run regardless of the environment variable’s presence.
Where exactly is the HERDR_ENV variable set in the source code?
The variable is injected during pane creation in src/pane.rs. Specifically, the spawn_with_initial_history and spawn_shell_command functions call cmd.env(crate::HERDR_ENV_VAR, crate::HERDR_ENV_VALUE) before launching the child process. This ensures every shell or command running inside a Herdr pane inherits HERDR_ENV=1.
What error appears when trying to run Herdr inside an existing Herdr pane?
The process exits with status code 1 after exit_if_nested_disabled (lines 94-100 in src/main.rs) prints a standard error message stating that nested Herdr is disabled by default. This is followed by a randomly selected string from the NESTED_HERDR_MESSAGES array, such as "inception detected. we need to go deeper... said no one ever."
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 →