WindowsでZenn CLIが動かないのを解決
ローカル執筆環境の構築
ZennにはWeb上のエディタで記事作成する方法とは別に、Zenn CLIというツールを使ってGitHubリポジトリと連携させることによりローカルのエディタで作成する方法があります。
Zennで発信し始めるにあたり、Webエディタではなく、使い慣れたローカル環境で執筆・管理したいと考えました。主な理由は以下の2点です。
-
記事も資産としてGit管理したい
アプリのコードと同様に、記事もバージョン管理し、ローカルとGitHubに完全なバックアップを保持したい。またZennがサービス終了したり他のサービスへ移行することになったとしても、記事テキストと画像が手元に残るようにしたい。 -
開発ワークフローと統合したい
普段の開発で使っているVSCode内で執筆から公開まで完結させたい。
当初は普段メモツールとして利用しているObsidianとの連携も目指したものの、技術的な問題(後述)により一部断念。最終的にVSCode (WSL接続) + Git + Zenn CLI を中心とした、執筆ワークフローを構築できたので、そこまでに至る試行錯誤の経緯をまとめます。
Step 0: GitHubリポジトリの準備
Zenn CLIを使うには、まず記事を管理するためのGitHubリポジトリが必要です。今回はソロプレナーとしての活動用のOrganizationを作成し、以下の構成にしました。
-
GitHub Organizationの作成
-
take-lab-devというOrganizationを作成
-
-
Privateリポジトリの作成
- 作成した
take-lab-devOrganization内に、zenn-contentsという名前でPrivateリポジトリを作成。 - Privateにした理由は、将来的にZennで有料記事を販売する可能性を考慮したため。Publicリポジトリにしてしまうと、有料記事のMarkdown原文が誰でも読めてしまうので。公開するような範囲はZennの記事で見れるのでPublicにする必要はないかと。
- 作成した
これでGitHub側の準備は完了。次はZenn CLIのセットアップです。
Step 1: Windows + Node.jsでのinit失敗
まずは公式からでているZenn CLIをインストールするに従い、PowerShell で作業を開始。当時の私の環境は Node.js v22.17.0 でした。
# GitHubからリポジトリをクローン (Google Driveの外に)
git clone https://github.com/take-lab-dev/zenn-contents.git
cd zenn-contents
Zenn CLIの初期化コマンドを実行すると、いきなり以下のエラーが発生。
> npx zenn-cli init
Need to install the following packages:
zenn-cli@0.2.8
Ok to proceed? (y) y
node:internal/url:1479
throw new ERR_INVALID_FILE_URL_PATH('must be absolute');
^
TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must be absolute
at getPathFromURLWin32 (node:internal/url:1479:11)
at fileURLToPath (node:internal/url:1510:35)
at C:\Users\xxxx\AppData\Local\npm-cache\_npx\213677bf7f5a4f63\node_modules\zenn-cli\dist\server\zenn.js:272:1660
at C:\Users\xxxx\AppData\Local\npm-cache\_npx\213677bf7f5a4f63\node_modules\zenn-cli\dist\server\zenn.js:293:2027
at Object.<anonymous> (C:\Users\xxxx\AppData\Local\npm-cache\_npx\213677bf7f5a4f63\node_modules\zenn-cli\dist\server\zenn.js:293:2031)
at Module._compile (node:internal/modules/cjs/loader:1730:14)
at Object..js (node:internal/modules/cjs/loader:1895:10)
at Module.load (node:internal/modules/cjs/loader:1465:32)
at Function._load (node:internal/modules/cjs/loader:1282:12)
at TracingChannel.traceSync (node:diagnostics_channel:322:14) {
code: 'ERR_INVALID_FILE_URL_PATH'
}
Node.js v22.17.0
initコマンドは、articlesやbooksといったフォルダを作るだけの単純なはずなのに。。。
Step 2: Node.jsバージョン比較
エラーメッセージではPATHがおかしいとしか書かれていないため原因が特定できず、まず疑ったのはNode.jsのバージョンでした。バグによる特定バージョンと互換性問題がある可能性を疑い、Node Version Manager (nvm-windows) を導入し、バージョンを切り替えながら試しました。
- Node.js v22.21.0 (LTS最新版)
> rm -r .\node_modules\
> rm .\package-lock.json
> nvm use lts
Now using node v22.21.0 (64-bit)
> npm install zenn-cli
added 1 package, and audited 2 packages in 1s
found 0 vulnerabilities
> npx zenn-cli init
node:internal/url:1489
throw new ERR_INVALID_FILE_URL_PATH('must be absolute', url);
^
TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must be absolute
at getPathFromURLWin32 (node:internal/url:1489:11)
at fileURLToPath (node:internal/url:1613:35)
at C:\zenn-contents\node_modules\zenn-cli\dist\server\zenn.js:272:1660
at C:\zenn-contents\node_modules\zenn-cli\dist\server\zenn.js:293:2027
at Object.<anonymous> (C:\zenn-contents\node_modules\zenn-cli\dist\server\zenn.js:293:2031)
at Module._compile (node:internal/modules/cjs/loader:1706:14)
at Object..js (node:internal/modules/cjs/loader:1839:10)
at Module.load (node:internal/modules/cjs/loader:1441:32)
at Function._load (node:internal/modules/cjs/loader:1263:12)
at TracingChannel.traceSync (node:diagnostics_channel:328:14) {
code: 'ERR_INVALID_FILE_URL_PATH',
input: file:///home/runner/work/zenn-editor/zenn-editor/node_modules/.pnpm/open@10.2.0/node_modules/open/index.js
}
Node.js v22.21.0
- Node.js v20.19.5
※zenn-cli@0.2.8を使うならNode.jsはv22以上を使えと怒られている
> rm .\package-lock.json
> rm -r .\node_modules\
> nvm use 20
Now using node v20.19.5 (64-bit)
> npm install zenn-cli
npm warn EBADENGINE Unsupported engine {
npm warn EBADENGINE package: 'zenn-cli@0.2.8',
npm warn EBADENGINE required: { node: '>=22.0.0' },
npm warn EBADENGINE current: { node: 'v20.19.5', npm: '10.8.2' }
npm warn EBADENGINE }
added 1 package, and audited 2 packages in 658ms
found 0 vulnerabilities
> npx zenn-cli init
node:internal/url:1459
throw new ERR_INVALID_FILE_URL_PATH('must be absolute');
^
TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must be absolute
at getPathFromURLWin32 (node:internal/url:1459:11)
at fileURLToPath (node:internal/url:1490:35)
at C:\zenn-contents\node_modules\zenn-cli\dist\server\zenn.js:272:1660
at C:\zenn-contents\node_modules\zenn-cli\dist\server\zenn.js:293:2027
at Object.<anonymous> (C:\zenn-contents\node_modules\zenn-cli\dist\server\zenn.js:293:2031)
at Module._compile (node:internal/modules/cjs/loader:1521:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1623:10)
at Module.load (node:internal/modules/cjs/loader:1266:32)
at Module._load (node:internal/modules/cjs/loader:1091:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:164:12) {
code: 'ERR_INVALID_FILE_URL_PATH'
}
Node.js v20.19.5
- Node.js v25.0.0
※v24の最新版にするつもりが、latestで指定したらv25だった
> rm .\package-lock.json
> rm -r .\node_modules\
> nvm install latest
25.0.0
Downloading node.js version 25.0.0 (64-bit)...
Extracting node and npm...
Complete
Installation complete.
If you want to use this version, type:
> nvm use 25
Now using node v25.0.0 (64-bit)
> npm install zenn-cli
added 1 package, and audited 2 packages in 590ms
found 0 vulnerabilities
> npx zenn-cli init
node:internal/url:1490
throw new ERR_INVALID_FILE_URL_PATH('must be absolute', url);
^
TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must be absolute
at getPathFromURLWin32 (node:internal/url:1490:11)
at fileURLToPath (node:internal/url:1614:35)
at C:\zenn-contents\node_modules\zenn-cli\dist\server\zenn.js:272:1660
at C:\zenn-contents\node_modules\zenn-cli\dist\server\zenn.js:293:2027
at Object.<anonymous> (C:\zenn-contents\node_modules\zenn-cli\dist\server\zenn.js:293:2031)
at Module._compile (node:internal/modules/cjs/loader:1759:14)
at Object..js (node:internal/modules/cjs/loader:1892:10)
at Module.load (node:internal/modules/cjs/loader:1479:32)
at Module._load (node:internal/modules/cjs/loader:1298:12)
at TracingChannel.traceSync (node:diagnostics_channel:328:14) {
code: 'ERR_INVALID_FILE_URL_PATH',
input: file:///home/runner/work/zenn-editor/zenn-editor/node_modules/.pnpm/open@10.2.0/node_modules/open/index.js
}
Node.js v25.0.0
- Node.js v24.10.0
> nvm install 24
Downloading node.js version 24.10.0 (64-bit)...
Extracting node and npm...
Complete
Installation complete.
If you want to use this version, type:
nvm use 24.10.0
> nvm use 24
Now using node v24.10.0 (64-bit)
> npm install zenn-cli
added 1 package, and audited 2 packages in 669ms
found 0 vulnerabilities
> npx zenn-cli init
node:internal/url:1490
throw new ERR_INVALID_FILE_URL_PATH('must be absolute', url);
^
TypeError [ERR_INVALID_FILE_URL_PATH]: File URL path must be absolute
at getPathFromURLWin32 (node:internal/url:1490:11)
at fileURLToPath (node:internal/url:1614:35)
at C:\zenn-contents\node_modules\zenn-cli\dist\server\zenn.js:272:1660
at C:\zenn-contents\node_modules\zenn-cli\dist\server\zenn.js:293:2027
at Object.<anonymous> (C:\zenn-contents\node_modules\zenn-cli\dist\server\zenn.js:293:2031)
at Module._compile (node:internal/modules/cjs/loader:1760:14)
at Object..js (node:internal/modules/cjs/loader:1893:10)
at Module.load (node:internal/modules/cjs/loader:1480:32)
at Module._load (node:internal/modules/cjs/loader:1299:12)
at TracingChannel.traceSync (node:diagnostics_channel:328:14) {
code: 'ERR_INVALID_FILE_URL_PATH',
input: file:///home/runner/work/zenn-editor/zenn-editor/node_modules/.pnpm/open@10.2.0/node_modules/open/index.js
}
Node.js v24.10.0
Node.js v20, v22, v24, v25 でnpx zenn-cli initは同じERR_INVALID_FILE_URL_PATHエラーで失敗。
この時点で、Node.jsのバージョンが直接の原因ではないと判断しました。
Zenn CLIも古いのを試すというのも考えられるが、キリがなく、今後もその古いバージョンを固定して使い続けるというのは嫌だったので試さず。
Step 3: エラーログの中のLinuxパス
エラーログをよく見返すと、よくわからないものを発見(v22.21.0, v24, v25で失敗した際のログ)。
code: 'ERR_INVALID_FILE_URL_PATH',
input: file:///home/runner/work/zenn-editor/zenn-editor/node_modules/.pnpm/open@10.2.0/node_modules/open/index.js
input: file:///home/runner/work... これはLinuxのファイルパスです。私はWindowsで作業しています。
zenn-cli またはその依存パッケージ(エラーログを見ると open というパッケージのよう)が開発・ビルドされた環境(おそらくGitHub ActionsのようなCI/CD環境)の絶対パスが、何らかの理由でパッケージのコード内にハードコード(埋め込み)されてしまっている可能性があり、Windows環境を正しく考慮していない形でLinuxのパスを参照しようとしてエラーになっているのではないか?という仮説に至りました。
Step 4: 【解決策】WSL (Windows Subsystem for Linux) の導入
もし原因がWindowsのパス処理の問題なら、zenn-cliが期待するであろうLinux環境で動かせば解決するはずです。そこで、WSL 2 (Ubuntu) を導入することにしました。
1. WSLのインストール
管理者権限でPowerShellを開き、wsl --installを実行。PC再起動後、Ubuntuのユーザー名とパスワードを設定。
2. VSCode - WSL 拡張機能
VSCodeにMicrosoft公式の「WSL」拡張機能をインストールし、VSCodeをWSL環境に接続。これでVSCodeのターミナルがUbuntuになりました。

Step 5: WSL環境での再挑戦
WSLのLinux環境を手に入れたので、VSCodeのターミナルを立ち上げ、再度zenn-cliのセットアップに挑戦しました。
1. Node.js LTS (v22) のインストール (WSL内)
# nvmのインストール (初回のみ)
$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
# ターミナル再起動
$ nvm install --lts # 最新LTS(v22)をインストール
$ nvm use --lts
$ node -v
v22.21.0
2. Zennリポジトリの準備 (WSL内)
$ cd ~ # ホームディレクトリへ移動
$ git clone https://github.com/take-lab-dev/zenn-contents.git
$ cd zenn-contents
$ npm install zenn-cli # ローカルにzenn-cliをインストール
added 1 package in 2s
3. 運命の init コマンド (WSL内)
ここまでは順調。ここで失敗しなければ・・・
$ npx zenn-cli init
🎉 Done!
早速コンテンツを作成しましょう
👇 新しい記事を作成する
$ npx zenn new:article
👇 新しい本を作成する
$ npx zenn new:book
👇 投稿をプレビューする
$ npx zenn preview
Done! やはりWindowsのパス処理が原因だったようです。
ちなみにWSL環境のディレクトリをWindowsのエクスプローラで開くのは
\\wsl$
または
`\\wsl.localhost\Ubuntu`
をアドレスバーでたたけばよい。
番外:Obsidian連携の検討
当初の目標だったObsidian連携も試みました。
既存Vaultの活用
普段使っているObsidianのVaultはGoogle Drive上に構築しています。ここにGitHubで連携するGit環境を構築してZenn記事投稿システムは構築できるのかをはじめに検討していました。
結論として、GitやGoogle Driveがそれぞれ同期するのにロックしたりすると、同期が失敗したり、ゴーストファイルが出来たり、最悪ファイルが壊れたりしないかということを懸念して断念。どちらにせよ、上記のWindowsパスの問題もあり難しかったかと。
新規Vaultをローカルドライブ上に作成
Windows版Obsidianから \\wsl$ パスを使ってWSL上の zenn-contents フォルダをVaultとして開こうとしてみると、ロード中にエラーが発生し開けない。

Error: EISDIR: illegal operation on a directory, watch '¥¥wsl.localhost¥Ubuntu¥home¥・・・
EISDIR: 「それはファイルではなく、ディレクトリ(フォルダ)」というエラー。
illegal operation on a directory, watch: Obsidianが「zenn-contents」フォルダ内の変更を監視(watch)しようとしたところ、「フォルダ全体を監視する」という操作が(WindowsとLinuxの境界をまたぐせいで)不正な操作だと判断され、失敗した様子。
WSL上にObsidianをインストールする方法もあるようですが、そこまで複雑にする必要はないと判断し、Obsidianはアイデア出し・下書き専用、外部にアウトプットするための清書以降はVSCode (WSL接続) で行うというワークフローに落ち着きました。
まとめ:WindowsでのNode.jsツール利用とWSL
今回の経験から学んだことは以下の通りです。
- GitHub準備は簡単: Organization作成、Privateリポジトリ作成は特に問題ない。
- Windows固有の問題: 特にファイルパスの扱いは、Linux前提で作られたツールで問題を起こしやすい。
- WSLの有効性: WSLは、このようなWindows固有の問題を回避し、Linuxツールを安定して動作させるための強力なソリューションとなる。
-
エラーログの重要性: 最初に試したバージョンでは出ずに違うバージョンで現れた
input: file:///home/runner/...のような小さな情報が、原因究明の大きな手がかりになった。 - ObsidianとWSL: Windows版ObsidianからWSL Vaultを直接開くことはできなさそう。
Windows環境でNode.js系のCLIツールが原因不明のエラーで動かない場合、GitHub等の準備はそのままに、WSL環境での実行を試してみる価値は非常に高そうです。
次回は、このWSL環境をベースに構築した、VSCode+Gitによる具体的なZenn執筆ワークフローについてまとめます。 → Zenn執筆環境をVSCode(WSL)+Gitで構築
Discussion