技術系(Tips)
PR

gh pr edit が “Projects (classic) is being deprecated” で失敗する問題は gh のアップデートで解決する

saratogax
記事内に商品プロモーションを含む場合があります

ある日突然、いつも使っている gh pr edit が GraphQL エラーで失敗するようになりました。

エラーメッセージを読むと「Projects (classic) is being deprecated」と書かれており、一見するとリポジトリ側の設定問題のように見えます。

結論から言うと、原因は gh CLI 側のバージョンが古いことで、brew upgrade gh で解決します。

本記事では、ハマった経緯と切り分け方法を残しておきます。

遭遇したエラー

PR の本文を更新しようとして以下のコマンドを実行したところ、エラーで失敗しました。

gh pr edit 123 --repo example-org/example-repo --body-file /tmp/body.md

返ってきたエラーは以下です。

GraphQL: Projects (classic) is being deprecated in favor of the new Projects experience, see: https://github.blog/changelog/2024-05-23-sunset-notice-projects-classic/. (repository.pullRequest.projectCards)

メッセージに repository.pullRequest.projectCards と書かれていることから、GraphQL クエリが旧 Projects (Projects classic) 関連のフィールドを参照しようとして拒否された、ということが読み取れます。

最初の誤解:リポジトリ側の問題だと思った

エラーメッセージに「Projects (classic) is being deprecated」と書かれているため、最初は該当リポジトリに古い Projects classic との連携が残っているのが原因だと考えました。

組織管理者でないと触れないような気もして、当面の回避策として GraphQL mutation を直接叩く方法に切り替えました。

gh api graphqlupdatePullRequest mutation を直接実行すれば、内部で projectCards フィールドを参照しないため成功します。

具体的には次の 2 ステップです。

PR の node ID を取得する

gh api graphql -f query='query { repository(owner:"OWNER", name:"REPO") { pullRequest(number:NUM) { id } } }' --jq '.data.repository.pullRequest.id'

updatePullRequest mutation を叩く

gh api graphql -F pullRequestId="<ID>" -F body=@/tmp/body.md -f query='mutation($pullRequestId: ID!, $body: String!) { updatePullRequest(input: {pullRequestId: $pullRequestId, body: $body}) { pullRequest { number url } } }'

これで PR の本文更新自体は通るのですが、毎回この長いコマンドを叩くのは現実的ではありません。

真の原因:gh CLI のバージョンが古かった

後日改めて切り分けてみると、手元の gh のバージョンを確認しただけで答えにたどり着けました。

gh --version を実行すると 2.62.0 (2024-11-14) と返ってきました。

執筆時点 (2026 年 4 月) からすると 1 年半も古いバージョンだったわけです。

原因の構造はこうなっていました。

  • サーバー側 (GitHub): Projects classic を deprecation し、関連する GraphQL フィールド (projectCards など) へのアクセスを段階的に拒否するようになった。
  • クライアント側 (古い gh): 内部的に projectCards フィールドを参照する古い GraphQL クエリを使い続けていた。
  • 結果: サーバーがリクエストを拒否してエラー。

新しい gh では projectCardsprojectItems (新 Projects 用フィールド) に切り替えるなどの対応が入っており、エラーは解消されています。

解決手順

Homebrew で gh を入れている場合、以下を実行するだけです。

brew upgrade gh

実行ログ:

==> Upgrading 1 outdated package:
gh 2.62.0 -> 2.91.0

アップグレード後にバージョンを確認します。

$ gh --version
gh version 2.91.0 (2026-04-22)

この状態で改めて gh pr edit を叩くと、エラーなく通るようになりました。

切り分けのポイント

同じような GraphQL deprecation エラーに遭遇したとき、ハマらないための切り分けの順序を整理しておきます。

確認の順序何を確認するかなぜ最初に確認するか
1手元の gh --versiondeprecation 系エラーの大半はクライアント側の追従漏れ
2他の人の環境で同じ操作が通るか通る人がいればローカル環境差 (バージョン or 設定) と確定
3対象リポジトリ・組織の Projects classic 連携1 と 2 で解決しなければ初めて疑う
※表は横スクロールできます

今回の私のケースは、エラーメッセージに「Projects (classic)」と書かれていたためにリポジトリ側を疑ってしまいました。

deprecation 系のエラーでは、まずクライアントのバージョンを最初に確認するというのが、シンプルで効果の高い習慣になりそうです。

回避策を残しておく価値

今回は gh のアップデートで解決しましたが、gh api graphqlupdatePullRequest mutation を直接叩く回避策自体は、覚えておく価値があります。

  • CI 環境など、gh を最新に保ちにくい状況でのワークアラウンド
  • 将来、別のフィールドが deprecation されて gh の追従が間に合わない時の応急処置
  • そもそも gh が対応していない GraphQL 操作 (review thread の resolve など) を行いたい時のテンプレート

「サブコマンドが内部で使う GraphQL フィールドが古い」という事象はまた繰り返されるはずなので、クライアント側の追従漏れを最初に疑う姿勢と、GraphQL mutation を直接叩いて回避できることを知っておくこと、この 2 つを引き出しに持っておくと安心です。

まとめ

  • gh pr edit の “Projects (classic) is being deprecated” エラーは、古い gh が deprecated GraphQL フィールドを参照しているのが原因である。
  • 解決は brew upgrade gh で十分で、手元の検証では 2.62.0 → 2.91.0 で解消した。
  • deprecation 系のエラーは、エラーメッセージ上の主語 (Projects classic 等) よりも先に、まずクライアントのバージョンを疑うのが近道である。
  • 応急処置として gh api graphqlupdatePullRequest mutation を直接叩く方法を引き出しに持っておくと安心である。
ABOUT ME
saratoga
saratoga
フリーランスエンジニア
仕事にも趣味にも IT を駆使するフリーランスエンジニア。技術的な TIPS や日々の生活の中で深堀りしてみたくなったことを備忘録として残していきます。
記事URLをコピーしました