個人開発で複数のサイトを Vercel にデプロイしています。ある日、デプロイしようとしたら失敗しました。次の日も失敗しました。
同じ「デプロイできない」でも、原因は別物でした。 昨日と同じだろうと決めつけていたら、切り分けをサボって余計に時間を溶かすところでした。
1日目:これは分かりやすい「上限」だった
npx vercel --prod --yes を叩いたら、こんなエラーが返ってきました。
Resource is limited - try again in 24 hours (code: "api-deployments-free-per-day")
これは読めば一発で分かります。無料プランの1日あたりのデプロイ回数上限に達したというエラーです。文言に「24 hours」「limited」とはっきり書いてあるので、迷う余地がありません。この日は「明日また叩けばいい」と判断して終わりました。
2日目:日付が変わったのに、また失敗した
翌日、「上限がリセットされたはず」と思って同じコマンドを叩きました。ところが、また失敗しました。
{ "status": "error", "reason": "deploy_failed", "message": "Not authorized" }
ここで最初、「あ、また上限か」と早合点しかけました。でもよく見ると、文言がまったく違います。前日は Resource is limited でしたが、今日は Not authorized(権限がない、認可されていない)です。エラー文言が別物なら、原因も別物のはずと考え直しました。
「Not authorized」の切り分け方
権限が無いと言われたので、順番に確認していきました。
① ログインは生きているか
npx vercel whoami
自分のアカウント名が返ってきました。ログイン自体は切れていません。
② このプロジェクトは個人のものか、チームのものか
プロジェクトの中にある .vercel/project.json を開くと、orgId という項目があります。
{
"orgId": "team_xxxxxxxxxxxxxxxxxxxxxxxx",
"projectId": "prj_xxxxxxxxxxxxxxxxxxxxxxxx"
}
orgId が team_ から始まっていました。つまりこのプロジェクトは個人アカウントではなく、チームの持ち物でした。
③ そのチームに自分は所属しているか
npx vercel teams ls
該当のチームがちゃんと一覧に出てきました。所属はしています。でも所属しているだけでは足りなかった、というのがこの話のオチです。
④ チームを名指しして再実行する
npx vercel --prod --yes --scope <チームのslug>
--scope オプションでチーム名を明示的に指定したら、あっさり通りました。
何が起きていたか
CLIでコマンドを叩くとき、Vercelは「今どのチームとして操作しているか」を内部で持っています。何らかの理由でその紐付けが外れると、「ログインはしている」「所属もしている」のに「今この操作をする権限が無い」という状態になるようです。ログインが切れているわけでも、招待が外れているわけでもないので、whoami を見ても異常には気づけません。--scope で毎回チームを名指しすれば、この曖昧さを避けられます。
まとめ
- 「デプロイできない」は原因が1つとは限らない。 前日と同じ操作でも、エラー文言が違えば原因を疑い直す
-
上限に当たっているときは、文言にはっきり「上限」「時間」の情報が入る(
Resource is limited - try again in 24 hoursのように)。読めば区別できる -
Not authorizedが出たら、vercel whoami(ログイン確認)→.vercel/project.jsonのorgId(個人かチームか)→vercel teams ls(所属確認)→--scope <チーム名>を付けて再実行、の順で切り分けると早い - 「昨日と同じ症状だろう」という思い込みが、切り分けを1段飛ばしにしてしまう一番の原因でした
この切り分けをしていたのは ShibaHub という無料の計算ツールを集めたサイトの本番反映作業中でした。ツールの解説記事をまとめて追加する作業がこれで1日遅れましたが、原因が分かってしまえば1分で直る話でした。