GitHubにIssueを書いたら、45日後に修正がマージされた ― Win32-OpenSSHのPATH問題

Issueの投稿から修正PRのマージまで45日

2026年9月16日に、Windows版のOpenSSH(Win32-OpenSSH)と、Node.jsのパッケージマネージャーであるpnpmに、それぞれ不具合を報告しました。それから45日後の10月31日、Win32-OpenSSH側で修正のPull Request(PR)がマージされ、私が立てたIssueもクローズされました。一方、pnpm側のIssueは、過去の報告との重複としてクローズされています。

先に正直に書いておくと、修正のコードを書いたのは私ではありません。私がしたのは、問題を調べてIssueにまとめたところまでです。そこから別の開発者が修正を書き、メンテナーがレビューして取り込んでくれました。私の報告が修正につながるところを最後まで追えたので、見つけてから直るまでの流れを残しておきます。

目次

SSHで入ったときだけ、pnpmが見つからなかった

WindowsマシンにSSHで接続して作業していたとき、ローカルでは普通に使えているpnpmが、SSHのセッションでは見つからないことに気づきました。最初は、pnpmの設定かPowerShellのどちらかの問題だろうと思っていたんです。

デスクトップで環境変数の設定画面を開くと、ユーザー環境変数の Path には次のように登録されていました。

%PNPM_HOME%\bin

これ自体はおかしな設定ではありません。Windowsでは、PATHに環境変数を参照する形のまま保存しておけます。デスクトップでPowerShellなどを起動すると、この参照が展開されて、たとえば PNPM_HOME が C:\Users\user\AppData\Local\pnpm なら、C:\Users\user\AppData\Local\pnpm\bin としてプロセスに渡されるんですね。ところが、SSH経由でPowerShellを起動して $env:Path を見ると、%PNPM_HOME%\bin が文字列のまま残っていました。

変数そのものは読めるのに、PATHの中だけ展開されない

不思議だったのは、$env:PNPM_HOME 自体は正しい値が取れることです。さらに調べると、%LOCALAPPDATA% や %USERPROFILE% のような変数は、SSHのセッションでもきちんと展開されていました。環境変数が使えないわけではなく、自分で定義した変数をPATHの中で参照したときだけ、うまくいかないようでした。

同じマシンで、同じユーザー環境変数なのに、デスクトップでは動いてSSHでは動かない。ここまで切り分けたところで、pnpm単体の問題ではなく、Win32-OpenSSHの環境変数の扱いが怪しいと考えるようになりました。

根本の修正と、当面の回避の両方を報告した

調べた結果、原因はWin32-OpenSSH側にあると考えました。ただ、pnpm側にも改善できる余地はあると思ったんです。

pnpmの pnpm setup コマンドは、ユーザー環境変数に PNPM_HOME を設定し、その参照を Path に追加します。Windowsの使い方としては合理的な設計です。それでも、Win32-OpenSSHの不具合がある環境では、pnpm本体も、pnpmでグローバルインストールしたCLIも見つからなくなってしまいます。

そこで9月16日に、2つのリポジトリへIssueを投稿しました。

  • Win32-OpenSSH: Issue #2456。PATHの中のユーザー定義変数が展開されない問題として、展開の順序そのものを直してほしいと報告しました。
  • pnpm: Issue #14975。pnpm setup が変数の参照ではなく、展開済みの絶対パスをPATHに登録するよう提案しました。

根本原因がWin32-OpenSSHにあるとしても、修正版がすべてのWindows環境に行き渡るまでには時間がかかります。pnpm側で対処できれば、古いOpenSSHのままの環境でも問題を避けられます。根本の修正と、互換性のための回避策の両方から報告した、という感覚でした。

Win32-OpenSSH側には、原因の見当まで書いた

Win32-OpenSSHのIssueには、「pnpmが動きません」とだけ書くのではなく、次の情報をまとめました。

  • 発生した環境とOpenSSHのバージョン
  • 問題を再現するためのPowerShellコマンド
  • 期待する結果と、実際の結果
  • 原因と考えられるソースコード上の処理
  • 修正方法の候補
  • 修正版が出るまでの回避策

中でも意識したのは、pnpmを入れなくても再現できるようにしたことです。MYTOOL_HOME というテスト用の環境変数を作り、それをPATHから参照する手順にしました。特定のツールに依存しない再現手順にしておけば、メンテナーも手元で確かめやすいだろうと考えたんです。

原因は、PATHを組み立てる順番だった

問題のコードは、Win32-OpenSSHのソースを管理している openssh-portable リポジトリの w32-doexec.c にありました。SSHのセッションを作るとき、処理はおおむね次の順番になっていました。

  1. システムとユーザーのPATHを取得する
  2. PATHの中の環境変数を展開する
  3. ユーザー定義の環境変数を設定する

PATHを展開する時点では、PNPM_HOME のようなユーザー定義の変数が、まだプロセスの環境に入っていません。そのため展開できなかった %PNPM_HOME% が文字列のまま残り、あとから PNPM_HOME が設定されても、PATHの展開はやり直されません。必要な変数がそろう前にPATHを組み立てていた、というのが私の見立てでした。Issueには、この順番の入れ替えを含めて、いくつかの修正案を書いています。

pnpm側は、4年前からの報告と重複していた

pnpm側のIssue #14975は、投稿から数日後の9月20日にクローズされました。同じ問題が、すでに報告されていたからです。

既存の Issue #5696「PNPM_HOME does not expand on Windows」 は、2022年11月26日に作られたものでした。私が報告するおよそ4年前から、Windowsでの PNPM_HOME の展開については報告されていたことになります。ただ、2022年の報告はWindowsでの展開の問題としてのもので、今回のようにWin32-OpenSSHの中の処理順序まで特定したものではありませんでした。

メンテナーは #14975 を #5696 の重複としてクローズしました。そのうえで、ここに書いた分析はこのIssueで読める形で残ること、2つに大事な違いがあるなら再オープンすることも書き添えてくれていました(出典: pnpm Issue #14975 のコメント)。提案した絶対パスへの変更が、このIssueを通じて実装されたわけではありません。pnpm側はいったんここで区切りになり、Win32-OpenSSH側のIssueだけがオープンのまま残りました。

ラベルは付いたものの、しばらくは何も動かなかった

Win32-OpenSSH側のIssueには、Area-sshd と Investigate のラベルが付きました。少なくとも、調査の対象として分類されたことは分かります。ただ、コメントが付くこともなく、そこからしばらく目立った動きはありませんでした。

Win32-OpenSSHは、普段それほど話題になるソフトウェアではありません。正直、このまま放置される可能性もあるなと思っていました。それでも気にはなっていたので、PRが作られていないか、メンテナーが動いていないかを定期的に見に行くことにしました。

43日目に修正PRが出て、2日後にマージされた

10月29日、Issueの投稿から43日後に、ようやく修正PRが作られました。PR #890「Fix PATH expansion order」 を作ったのは、GitHubユーザーの o-sdn-o さんです。内容はシンプルで、これまで setup_session_user_vars() の中にあったPATHの組み立てを切り離し、新しく setup_session_user_path() という関数にしたうえで、ユーザーの環境変数を設定したあとにPATHを組み立てるよう変えたものでした。

修正前: PATHの構築 → ユーザー変数の設定
修正後: ユーザー変数の設定 → PATHの構築

まさに、Issueで指摘していた順番の問題に対する修正でした。

テストを足して、レビューを通してからマージされた

PRは作られて終わり、というわけではありませんでした。10月30日には、メンテナーの tgauth さんから、Issueに出てきた %PNPM_HOME% のようなユーザー定義の変数についてもテストを追加してほしい、という依頼が入りました(出典: PR #890 のコメント)。それを受けて、PRの作成者が既存の環境変数のテストを広げています。

GitHub Copilotによるコードレビューでは、テストがユーザープロファイルのパスを決め打ちしている点も指摘されていました。こちらも修正され、再レビューでは未解決の指摘がなくなっています。動きそうだから取り込むのではなく、実際の不具合を再現するテストを足して、別のWindows環境でも通ることを確かめていく。PRの履歴を追っているだけでも、なかなか勉強になりました。

そして日本時間の10月31日0時54分ごろ、PR #890がマージされ、私のIssue #2456も同時にクローズされました。最終的な変更は2ファイルで、Windows側の環境変数の処理(w32-doexec.c)と、それを確かめるPowerShellのテストコードです。

問題に気づいて原因を報告したのは利用者で、修正したのは別の開発者、それをメンテナーがレビューして取り込む。オープンソースでは当たり前の流れなのかもしれませんが、私の報告が実際に直るところまで見られたのは、なかなかうれしい経験でした。

マージされても、修正版はまだ配布されていない

ここは注意が必要です。2026年11月1日時点で、修正のコードはマージされていますが、修正を含むWindows向けのバイナリはまだ配布されていません。10月20日に公開されたPreview版(10.4.0.0p1-Preview)には、今回の修正は含まれていません。

そのため、今使っている環境では当面、回避策が必要です。私の環境では、ユーザー環境変数の Path にある %PNPM_HOME%\bin を、展開済みの絶対パス(例: C:\Users\user\AppData\Local\pnpm\bin)に書き換えたところ、SSHのセッションでもpnpmが動くようになりました。新しいリリースに修正が入ったら、変数参照のままでも動くかを実機で確かめてみるつもりです。

同じ不具合でも、プロジェクトによって答えは違った

今回感じたのは、Issueの価値は「困っています」と伝えることだけではない、ということです。再現手順、期待する結果と実際の結果、原因の見当まで整理しておくと、開発者が問題をつかみやすくなる気がします。マージされたPRがIssueで書いた順番の話とそのまま重なっていたのを見て、そう思いました。

同じ不具合でも、プロジェクトによって扱いが違うことも分かりました。pnpm側では既存Issueとの重複としてクローズされ、Win32-OpenSSH側では修正につながっています。ただ、これはどちらの判断が正しいという話でもないと思っています。pnpmが環境変数を使うこと自体は正常な設計で、直接の原因はWin32-OpenSSHがそれを正しく扱えなかったことです。一方で、pnpm側が絶対パスを登録するのも、古い環境との互換性を上げる選択肢ではあります。利用者とメンテナーとでは、見ている範囲が違うんだと思います。

Issueは投稿した瞬間に直るものではありませんが、投稿しなければ問題を共有する機会もなくなります。自分でPRを送らなくても、再現できる形で問題を報告することで、オープンソースに関わることはできるんですね。

まとめ

今回の流れを並べると、こうなります。

  • 9月16日: Win32-OpenSSHとpnpmにIssueを投稿
  • 9月20日: pnpm側は既存Issue #5696との重複としてクローズ
  • 10月29日: Win32-OpenSSH側に修正PR #890が作られる
  • 10月30日: メンテナーの依頼でテストを追加、レビュー指摘も修正
  • 10月31日: PRがマージされ、Issue #2456もクローズ

普段なんとなく使っているツールで不具合に当たったら、まずは原因を切り分けてみて、できそうならIssueに残してみる。再現手順と「期待する結果/実際の結果」があるだけでも、受け取る側の手間はだいぶ減る気がします。私自身は、次に新しいリリースが出たら、変数参照のままでpnpmが動くかを確かめるところからです。

参考文献

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次