iw start on a tmux server that already runs gives the pane that server's IW_* values #572

Open
opened 2026-09-16 13:35:36 +00:00 by claude · 1 comment
Member

Problem

tmux builds a new session's environment from the server's global environment. The environment of the client process that runs new-session reaches the server only when that client starts the server.

TmuxAdapter.createSessionIn (core/adapters/Tmux.scala) passes the filtered map from sessionEnv as the tmux client's process environment, with propagateEnv = false. That filter takes effect only when iw start itself starts the server. On a server that already runs, the pane gets the server's IW_* values: plumbing names such as IW_COMMANDS_DIR or IW_PLUGIN_DIRS, and the server's IW_HOME.

How likely

Low. The server's global environment must hold plumbing names. That needs a server started by an iw older than 1daf4fa0, or from a shell that exports those names. The IW-556 investigation created this state by hand; nothing shows it happens in practice.

Reproduction script: project-management/issues/IW-556/analysis.md, Defect 2 (iw-556-server-reuse.sh).

Constraint for a fix

new-session -e NAME=value overrides the server's value, but it freezes the value for the session's life. Do not pass IW_HOME or any non-IW_ variable that way: a developer's tmux config can remove such variables from the server on purpose, so the shell (fish) supplies a live value. See the superseded Decisions D1 and D2 in the IW-556 analysis. Removing only plumbing names with -e NAME= (empty value, which iw-run treats as unset) is the candidate; set-environment -u after new-session does not change the first pane.

Found while working IW-556.

## Problem tmux builds a new session's environment from the **server's** global environment. The environment of the client process that runs `new-session` reaches the server only when that client starts the server. `TmuxAdapter.createSessionIn` (`core/adapters/Tmux.scala`) passes the filtered map from `sessionEnv` as the tmux client's process environment, with `propagateEnv = false`. That filter takes effect only when `iw start` itself starts the server. On a server that already runs, the pane gets the server's `IW_*` values: plumbing names such as `IW_COMMANDS_DIR` or `IW_PLUGIN_DIRS`, and the server's `IW_HOME`. ## How likely Low. The server's global environment must hold plumbing names. That needs a server started by an `iw` older than `1daf4fa0`, or from a shell that exports those names. The IW-556 investigation created this state by hand; nothing shows it happens in practice. Reproduction script: `project-management/issues/IW-556/analysis.md`, Defect 2 (`iw-556-server-reuse.sh`). ## Constraint for a fix `new-session -e NAME=value` overrides the server's value, but it freezes the value for the session's life. Do **not** pass `IW_HOME` or any non-`IW_` variable that way: a developer's tmux config can remove such variables from the server on purpose, so the shell (fish) supplies a live value. See the superseded Decisions D1 and D2 in the IW-556 analysis. Removing only plumbing names with `-e NAME=` (empty value, which `iw-run` treats as unset) is the candidate; `set-environment -u` after `new-session` does not change the first pane. Found while working IW-556.
Author
Member

Intake: needs-input
Workflow: diagnostic
Reason: G1 (1 CLARIFY marker)
Analysis: project-management/issues/IW-572/analysis.md on branch IW-572

1. When an iw session starts on a tmux server that already runs, how should iw remove the leaked internal IW_* paths? (G1)

A tmux server that runs already gives each new pane its own environment, and that environment can hold internal iw paths such as IW_COMMANDS_DIR or IW_PLUGIN_DIRS. The agent's iw in that pane then loads code from a different place, and nothing reports it. The issue suggests an empty value for each session. A probe showed that in fish an empty inherited value hides a universal variable (set -Ux) that has the same name. IW_PLUGIN_DIRS is a documented user setting (README.md#L158). Full comparison: analysis.md#L250-L257. Probe results: analysis.md#L171-L172.

  • a) Give each name an empty value in iw's session only (new-session -e NAME=). Only iw's session changes. In iw panes, a user's fish set -Ux IW_PLUGIN_DIRS stops working. The assertions at start.bats#L169-L171 change from "name absent" to "no usable value".
  • b) Remove the names from the whole server (set-environment -gu NAME) in the same tmux call, before new-session. The names are absent, and fish universals continue to work. The cost: iw changes a server that it did not start, so sessions that are not iw sessions and start later on that server also lose these names. This also works when no server runs yet (review note 1).

Recommended: b) — These internal paths are wrong in every pane, and the developer's tmux config already uses -gu for the same fish reason.

Answer in a comment on this issue, per number, for example "1: a", or in your own words; intake reads it on its next iteration.

Intake: needs-input Workflow: diagnostic Reason: G1 (1 CLARIFY marker) Analysis: project-management/issues/IW-572/analysis.md on branch IW-572 ### 1. When an iw session starts on a tmux server that already runs, how should iw remove the leaked internal IW_* paths? (G1) A tmux server that runs already gives each new pane its own environment, and that environment can hold internal iw paths such as `IW_COMMANDS_DIR` or `IW_PLUGIN_DIRS`. The agent's `iw` in that pane then loads code from a different place, and nothing reports it. The issue suggests an empty value for each session. A probe showed that in fish an empty inherited value hides a universal variable (`set -Ux`) that has the same name. `IW_PLUGIN_DIRS` is a documented user setting ([README.md#L158](https://code.iterative.works/iterative-works/iw-cli/src/branch/IW-572/README.md#L158)). Full comparison: [analysis.md#L250-L257](https://code.iterative.works/iterative-works/iw-cli/src/branch/IW-572/project-management/issues/IW-572/analysis.md#L250-L257). Probe results: [analysis.md#L171-L172](https://code.iterative.works/iterative-works/iw-cli/src/branch/IW-572/project-management/issues/IW-572/analysis.md#L171-L172). - **a) Give each name an empty value in iw's session only (`new-session -e NAME=`).** Only iw's session changes. In iw panes, a user's fish `set -Ux IW_PLUGIN_DIRS` stops working. The assertions at [start.bats#L169-L171](https://code.iterative.works/iterative-works/iw-cli/src/branch/IW-572/test/start.bats#L169-L171) change from "name absent" to "no usable value". - **b) Remove the names from the whole server (`set-environment -gu NAME`) in the same tmux call, before `new-session`.** The names are absent, and fish universals continue to work. The cost: iw changes a server that it did not start, so sessions that are not iw sessions and start later on that server also lose these names. This also works when no server runs yet ([review note 1](https://code.iterative.works/iterative-works/iw-cli/src/branch/IW-572/project-management/issues/IW-572/analysis.md#L340)). **Recommended: b)** — These internal paths are wrong in every pane, and the developer's tmux config already uses `-gu` for the same fish reason. Answer in a comment on this issue, per number, for example "1: a", or in your own words; intake reads it on its next iteration.
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
iterative-works/iw-cli#572
No description provided.