Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

fix(admin): batch param is unclamped and batch=0 spins 50 no-op batches in all=true mode

オープン 初心者向け
#28 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
76/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
活発
技術スタック
typescript
領域
api, backend

調査の方向性

apps/web/app/routes/api.admin.recompute.ts の parseIntSafe、batchSize の代入、all=true ループから始め、検証処理を recompute-all-skills.ts:177 に記載された挙動と比較します。必要な D1 および KV bindings を指定した、提供されている ADMIN_SECRET curl 再現手順を使用し、その後 batch の値に上限が設定され、batch=0 が 50 個の no-op batch を生成しなくなっていることを確認します。

索引モデルが issue の本文から書いたものです。

説明

bug

Summary

The batch query parameter is neither clamped nor range-checked on POST /api/admin/recompute. parseIntSafe rejects only NaN and negative values, so batch=0 is accepted and there is no upper bound either. With all=true, batch=0 makes one request burn all 50 permitted batch iterations while processing nothing.

Current behavior

  • apps/web/app/routes/api.admin.recompute.ts:28-32 — the only validation, which lets 0 through and caps nothing:
    function parseIntSafe(value: string | null, fallback: number): number {
      if (value == null) return fallback;
      const n = parseInt(value, 10);
      return Number.isNaN(n) || n < 0 ? fallback : n;
    }
    
  • apps/web/app/routes/api.admin.recompute.ts:58 — that value becomes batchSize and reaches .limit(batchSize) in the query builder, so batch=0 becomes LIMIT 0.
  • apps/web/app/lib/leaderboard/recompute-all-skills.ts:177 — with an empty batch the completion test is 0 < 0, which is false:
    const isComplete = batch.length < batchSize;
    
    The batch is reported as incomplete, and nextOffset is set to offset unchanged, so the all=true loop at apps/web/app/routes/api.admin.recompute.ts:81 keeps calling with the same offset until MAX_BATCHES_PER_REQUEST (50) is reached, then returns "Paused after 50 batches" with nothing processed.
  • There is also no upper bound: batch=100000 is accepted and would defeat the guard added at line 21 to keep the Worker under its CPU limit.

Expected behavior

Clamp the value to a sane range, as the review recommended, and reject nonsense input explicitly:

const batchSize = Math.min(Math.max(parseIntSafe(batch, 100), 1), 500);

Reproduction

  1. Set batch to 0 and select all-at-once mode:
    ADMIN_SECRET=... curl -sS -X POST "https://skillx.sh/api/admin/recompute?all=true&batch=0"
    
  2. The response reports batches: 50, totalProcessed: 0, and the "Paused after 50 batches" message, while GET /api/admin/recompute shows the checkpoint unchanged.

Conditions: requires ADMIN_SECRET plus the D1 and KV bindings; admin-only endpoint. Behavior read from main at 9d0f9e9; the exact request was not executed against production.

Flow

flowchart LR
  A["batch=0"] --> B[parseIntSafe returns 0]
  B --> C["LIMIT 0 -> empty batch"]
  C --> D{{"isComplete = 0 < 0 = false"}}
  D -->|nextOffset unchanged| E[all=true loop retries same offset]
  E --> F[50 no-op batches, then Paused]

Evidence

  • Affected code: apps/web/app/routes/api.admin.recompute.ts:28, apps/web/app/routes/api.admin.recompute.ts:58, apps/web/app/routes/api.admin.recompute.ts:81, apps/web/app/lib/leaderboard/recompute-all-skills.ts:177
  • Introduced by: 88a5bff, shipped on main via 9d0f9e9 (PR #9)
  • Related: plans/reports/code-reviewer-260306-1531-admin-recompute-endpoint.md, section "8. Input validation for batch and offset params"

Open questions

  • Upper bound: 500 as suggested in the review, or align it with the existing default of 100?
  • Should batch=0 return HTTP 400 instead of being silently clamped to 1?

Notes

  • offset has the same missing upper clamp, but an out-of-range offset only yields an empty batch and a correct completion, so it is far less harmful than batch=0.
  • MAX_BATCHES_PER_REQUEST at line 21 already handles the Worker-timeout risk from the review; the missing piece is bounding the work each iteration can request.
主要言語
TypeScript
スター
189
フォーク
40
平均マージ
6時間 54分
マージ済み PR(30日)
24

環境構築

このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

nextlevelbuilder/skillx のほかの issue

nextlevelbuilder/skillx の issue をすべて見る

似ている issue

TypeScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。