$FORGE_CHANNEL names the wrong channel #22

Closed
opened 2026-08-03 08:22:21 +01:00 by pedromcaraujo · 0 comments

modules/ttyd.nix sets FORGE_CHANNEL (and CLAUDE_CHANNEL) per ttyd unit,
documented as "exported into the session so a statusline script can render
which channel it is". It doesn't work.

The channels share one long-lived tmux server, spawned lazily by whichever
ttyd starts first. new-session -A only carries tmux's update-environment
allowlist across, so every session created afterwards inherits the server's
environment — i.e. the first channel's FORGE_CHANNEL.

Verified live: a pane in tmux session forge reports FORGE_CHANNEL=vault.

So any statusline reading it labels almost every channel wrongly, and it gets
worse the more channels there are — only the one that happened to spawn the
server is correct.

Fix

Resolve the channel from the pane instead:

tmux display-message -p -t "$TMUX_PANE" '#{session_name}'

That is what web/forge-status-hook.sh does (see #21) and it is correct in
every session. Either drop the two variables and document the tmux lookup, or
have the session command re-export them from the resolved session name before
exec'ing sessionCommand — the launcher script already re-sources env inside
the session for exactly this class of reason.

Also update the comment at the top of modules/ttyd.nix, which currently
states the broken contract.

`modules/ttyd.nix` sets `FORGE_CHANNEL` (and `CLAUDE_CHANNEL`) per ttyd unit, documented as "exported into the session so a statusline script can render which channel it is". It doesn't work. The channels share **one** long-lived tmux server, spawned lazily by whichever ttyd starts first. `new-session -A` only carries tmux's `update-environment` allowlist across, so every session created afterwards inherits the *server's* environment — i.e. the first channel's `FORGE_CHANNEL`. Verified live: a pane in tmux session `forge` reports `FORGE_CHANNEL=vault`. So any statusline reading it labels almost every channel wrongly, and it gets worse the more channels there are — only the one that happened to spawn the server is correct. ## Fix Resolve the channel from the pane instead: tmux display-message -p -t "$TMUX_PANE" '#{session_name}' That is what `web/forge-status-hook.sh` does (see #21) and it is correct in every session. Either drop the two variables and document the tmux lookup, or have the session command re-export them from the resolved session name before exec'ing `sessionCommand` — the launcher script already re-sources env inside the session for exactly this class of reason. Also update the comment at the top of `modules/ttyd.nix`, which currently states the broken contract.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
pedromcaraujo/forge#22
No description provided.