マキモノ
開発プロセス無料✅ 公式検証済みv1.0.0 / 更新

ダッシュボードが「artifact が見つからない」で真っ赤になるのを塞ぐ

GitHub Actions の成果物を画面に出す構成が no valid artifacts found で落ちる真因(preflight skip した run も success だが artifact 無し)と、artifact 実在確認+直近成功へのフォールバックで画面を殺さない直し方。常駐プロセスの世代確認と実ブラウザ描画までの検証手順つき。

出品者: kim@orgiast.jp📖 読込 約2,703トークン (約4円)💰 コスパ 13
トークン節約メーター86%節約
ゼロからAIに作らせた場合4.2万トークン
このMDを読ませた場合6,000トークン

3.6万トークンの節約 (API料金換算で約54円分)。 要件定義・技術調査・試行錯誤ぶんのトークンがまるごと不要になります。※ 出品者申告とレビューに基づく推定値。モデル・タスク内容により変動します。

この巻物について

ダッシュボードが「artifact が見つからない」で真っ赤になるのを塞ぐ」は、開発プロセスカテゴリのAI指示書(MDファイル)です。GitHub Actions の成果物を画面に出す構成が no valid artifacts found で落ちる真因(preflight skip した run も success だが artifact 無し)と、artifact 実在確認+直近成功へのフォールバックで画面を殺さない直し方。常駐プロセスの世代確認と実ブラウザ描画までの検証手順つき。この巻物をAIに読み込ませると、ゼロから設計・調査する場合に比べて 約3.6万トークン(API料金換算で約54円)・86%のトークンを節約できます。

カテゴリ
開発プロセス
対応AI
claude-code、cursor、codex-cli
ライセンス
商用利用可 (再販不可)
価格
無料
ゼロから開発時
約4.2万トークン
この巻物使用時
約6,000トークン
節約量
約3.6万トークン (約54円)
更新日
2026-09-12

使い方 (AIに渡す3つの方法)

いちばん簡単なのはワンライナー。Claude Code のターミナルに貼るだけです。

⬇ .md をダウンロード
claude "https://makimono-md.vercel.app/api/v1/files/artifact/raw を読み込んで、この指示書どおりに実装して"
claude-codecursorcodex-cliライセンス: 商用利用可 (再販不可)

中身

ダッシュボードが「artifact が見つからない」で真っ赤になるのを塞ぐ

GitHub Actions が作った成果物(artifact)を別のアプリから gh run download で取ってきて画面に出す構成は、 ある日突然 no valid artifacts found to download で落ちて、パネルが赤いエラーだけになる。 このドキュメントは、その真因と、二度と赤くしないための直し方を扱う。

症状

ダッシュボードのパネルに、データの代わりにこれが出る。

取得失敗: gh failed (1): no valid artifacts found to download

workflow は緑(成功)で、GitHub の画面上は何も壊れていないように見える。それなのに取得だけが落ちる。

真因: 「成功した run」と「成果物がある run」は別物

多くの実装は取得元をこう選んでいる。

// ありがちな実装 — 壊れる
const runs = await gh(`run list --workflow=<workflow ファイル名> --status=success --limit 1 --json databaseId`);
const runId = runs[0].databaseId;
await gh(`run download ${runId} --name <artifact 名> --dir <保存先>`);

これは「成功 run は必ず成果物を持っている」という前提に立っている。この前提は次の場合に崩れる。

  1. preflight で早期 skip する workflow 1日に複数回走るスケジュール実行で、「今日はもう成功しているから処理不要」と判定して早期 return する 設計はよくある。この run は失敗ではないので conclusion: success のまま残るが、 本処理を通っていないので artifact をアップロードしていない
  2. artifact の保持期限切れ(既定90日、リポジトリ設定で短縮されていることがある)。 run のメタデータは残るが artifact だけ消える。
  3. matrix / 条件付き job で、その run では artifact を作る job が走らなかった。

どれも run のステータスだけ見ていると区別できない。実測すると一目でわかる。

# 「最新の成功 run」の artifact を数える
gh api repos/<owner>/<repo>/actions/runs/<最新の成功runId>/artifacts --jq '.total_count'
# → 0   ← これが真因。1つ前の run には入っている

直し方1: artifact の実在を確認してから採用する

1件目で決め打ちせず、成功 run を新しい順に走査して「artifact を実際に持っている run」を選ぶ。

const MAX_SCAN = 20; // 走査する成功 run の上限

async function runHasArtifacts(runId) {
  const json = await gh(
    `api repos/<owner>/<repo>/actions/runs/${runId}/artifacts --jq '.total_count'`
  );
  return Number(json.trim()) > 0;
}

async function pickRunWithArtifacts() {
  const runs = await gh(
    `run list --workflow=<workflow ファイル名> --status=success ` +
    `--limit ${MAX_SCAN} --json databaseId,createdAt,event`
  );
  for (const run of runs) {           // 新しい順
    if (await runHasArtifacts(run.databaseId)) return run;
  }
  return null;                        // 20件見て無ければ諦める
}

--limit は控えめで良い。走査は run 1件につき API 1回なので、20件でもレート制限には遠い。 「保持期限切れが常態化している」ようなリポジトリでは、そもそも上流を直す方が先。

直し方2: 取れなかった時こそ画面を殺さない(こちらが本命)

直し方1 は「artifact がある run を見つけられる場合」の対策でしかない。 上流のジョブが止まっている・全部期限切れ、という日は必ず来る。そこで最後に成功した内容をディスクに 保存しておき、取得に失敗したらそれを出す

const CACHE = '.cache/<機能名>-last-success.json';

async function getLatest({ force = false } = {}) {
  try {
    const data = await fetchFromArtifact();          // 直し方1 を使う
    fs.mkdirSync(path.dirname(CACHE), { recursive: true });
    fs.writeFileSync(CACHE, JSON.stringify({ data, savedAt: new Date().toISOString() }));
    return { ...data, _stale: false, _staleError: null };
  } catch (error) {
    if (fs.existsSync(CACHE)) {
      const cached = JSON.parse(fs.readFileSync(CACHE, 'utf8'));
      return { ...cached.data, _stale: true, _staleAt: cached.savedAt, _staleError: String(error) };
    }
    throw error;                                     // 初回だけは本当に出すものが無い
  }
}

画面側は _stale を見てエラー表示ではなく警告バナー付きの実データにする。

{data._stale && (
  <div className="warn">
    最新の取得に失敗したため過去データを表示中(最終更新: {formatDate(data._staleAt)})
  </div>
)}
<RealContent data={data} />

なぜこれが本命か: データが5日古いことより、画面が真っ赤で何も読めないことの方が害が大きい。 週次レポートのような更新頻度の低いデータなら、多少古くても判断には十分使える。 「取得できないなら何も出さない」は一見誠実だが、運用上は単なる機能停止になる。

キャッシュファイルは .gitignore に入れること(.cache ごと除外でよい)。

やってはいけない直し方

  • --limit を増やすだけ: 走査件数を増やしても、実在確認をしなければ結局 artifact 無しの run を掴む。
  • エラーを握り潰して空を返す: 画面は静かになるが、上流が止まっていることに誰も気づけなくなる。 _stale を必ず画面に出し、いつのデータかを明示する。
  • workflow 側の preflight skip を消す: 毎回フル実行に戻すと実行時間と課金が増える。 skip 自体は正しい設計なので、取得側を賢くする。

検証(ここまでやって「直った」と言う)

ステータスコードや単体テストだけでは不十分で、人が実際に見る画面まで確認する。

  1. 修正後の取得関数を直接実行し、artifact 無しの run をスキップして正しい run を採用することを確認する。

  2. 常駐プロセスが修正後のコードで動いているかを確認する。 ここが一番よく抜ける — 開発サーバで通っても、利用者が見ているのは何日も前に起動した常駐プロセスである。

    # そのポートを掴んでいるプロセスの起動時刻 < 修正のコミット時刻 なら古いコードで動いている
    # (Windows)
    powershell -NoProfile -Command "Get-NetTCPConnection -LocalPort <port> | Select-Object OwningProcess"
    powershell -NoProfile -Command "Get-Process -Id <pid> | Select-Object Id,StartTime"
    # (Linux/macOS)
    lsof -ti tcp:<port> | xargs ps -o pid,lstart,command -p
    

    古ければ再起動してから次へ進む。

  3. 実ブラウザで描画テキストを取り、エラー文字列が消えたことを確認する。 クライアント描画のフレームワークでは curl の HTML に本文が出ないので、ヘッドレスブラウザを使う。

    const panel = page.locator('<パネルのセレクタ>').filter({ hasText: '<パネル見出し>' }).first();
    await panel.waitFor({ state: 'visible' });
    const text = await panel.innerText();
    console.log('HAS_ERROR', text.includes('取得失敗') || text.includes('no valid artifacts'));
    await panel.screenshot({ path: '<保存先>.png' });
    

    スクリーンショットまで取れば、「直ったはず」ではなく「直っている」と言える。

応用先

同じ「成功 = 成果物あり」の思い込みは、次の場所にも同型で潜んでいる。

  • 最新のリリース資材を取りに行く処理(draft/prerelease を弾いていない)
  • 最新のビルド成果物をデプロイする処理(キャッシュヒットで成果物を作らなかった run を掴む)
  • 最新のバックアップを復元する処理(0 バイトのファイルを「存在する」と判定する)

いずれも**「ステータス」ではなく「実際に欲しいものが入っているか」で選ぶ**、 取れなかった時に直前の成功を出す、の2点で同じように塞げる。

よくある質問

「ダッシュボードが「artifact が見つからない」で真っ赤になるのを塞ぐ」とは何ですか?

GitHub Actions の成果物を画面に出す構成が no valid artifacts found で落ちる真因(preflight skip した run も success だが artifact 無し)と、artifact 実在確認+直近成功へのフォールバックで画面を殺さない直し方。常駐プロセスの世代確認と実ブラウザ描画までの検証手順つき。

どれくらいトークン(費用)を節約できますか?

ゼロから開発すると約4.2万トークンかかりますが、この巻物を使えば約6,000トークンで済みます。差し引き約3.6万トークン(API料金換算で約54円)・86%の節約です。

どうやって使いますか?

無料です。MDファイルを Claude Code などのAIに読み込ませるだけ。ワンライナーをターミナルに貼れば実装が始まります。要件定義や技術調査を省いて実装だけにトークンを使えます。

どのAIツールに対応していますか?

claude-code、cursor、codex-cli に対応しています。

商用利用できますか?

ライセンスは「商用利用可 (再販不可)」です。

🤝 自分でAIを動かすのは、まだ不安…という方へ

この巻物の内容を、AIを使うプロに丸ごと任せることもできます。姉妹サービスAI代行堂なら「LINEで頼むだけで、仕事が完成」。

AI代行堂を見る →

関連する巻物

この巻物、誰かのトークンも救えます

𝕏 で節約レシートをシェア