AI Integration Problems Jul 12, 2026

GitHub Issues API Returns 422 When Whisper Batch Body Contains Invented Repro Steps - How to Fix

Fix GitHub Issues API 422 errors when Whisper playtest batch automation submits invented repro steps. Issue form schema pass, quote-only bodies, build_id from BUILD_RECEIPT, gh dry-run, and whisper_issue_tag_receipt_v1.json gate.

By GamineAI Team

GitHub Issues API Returns 422 When Whisper Batch Body Contains Invented Repro Steps - How to Fix

Problem: Your playtest triage script calls POST /repos/{owner}/{repo}/issues (or gh issue create) after a Whisper batch night and GitHub responds 422 Unprocessable Entity. The automation log shows validation errors on body, labels, or issue form fields—while curl rate limits and 401 auth are not the cause. Batch triage stalls; facilitators paste the same LLM draft into the web UI and get the same rejection.

Who is affected now: Micro-studios running June–October 2026 Whisper→GitHub tag extraction with structured issue forms and nightly gh automation. GitHub validates issue bodies against YAML form schemas; LLM summaries that add “Repro steps (guess)”, hardware steps the player never said, or empty required fields fail before an issue is created. This is payload validation, not MKV concat failure (no transcript) or OpenAI 413 chunking (cloud Whisper size).

Fastest safe fix: Stop the batch job → open the 422 response JSON → remove invented repro → submit quote-only body with build_id from BUILD_RECEIPT → run gh issue create --dry-run (or REST preview) → set github_payload_ok: true on whisper_issue_tag_receipt_v1.json → retry API with minimal body + labels that exist on the repo.

Direct answer

422 means GitHub rejected the issue payload, not that Whisper failed. Playtest triage bots often paste LLM-expanded repro that violates your issue form (“repro steps known?” dropdown) or exceeds field rules. Fix the body, not the transcript: verbatim player quote, build_id, fragment_id, and “No — quote-only triage” unless the tester literally stated steps. Run gh issue create --dry-run before W6 marks github_issue_allowed: true.

Why this issue spikes in June–October 2026

  1. Issue forms adoption — Teams enable GitHub Issue forms to block free-text repro; API payloads must match form field IDs.
  2. Whisper batch nightsLocal Whisper pipeline produces transcripts; facilitators want same-night GitHub issues.
  3. LLM assist creep — Summaries add “click Settings → Graphics” steps not in the transcript—W4 discipline exists in Guide #28 preflight but batch scripts skip the human gate.
  4. BUILD_RECEIPT gatesLesson 266 fails promotion when whisper_issue_tag_ok is false after 422 storms.
  5. November fest close-outjq capstone crosswalk treats missing tag receipt as child receipt RED.

Symptoms and search phrases

  • HTTP 422 on POST .../issues with "message": "Validation Failed".
  • gh issue create exits 1; stderr mentions issue form or required field.
  • Body contains “Repro steps (automated)” or GPU/driver steps absent from transcript.
  • Labels like P0-blocker rejected—label does not exist on repo.
  • build_id field empty or copied from Discord instead of BUILD_RECEIPT.
  • Rate limit (403) confused with validation—422 has no Retry-After for payload fix.
  • Web UI “Create issue” works with manual quote-only paste but API fails with bot body.

Root causes (check in order)

  1. Invented repro steps in body—violates quote-only policy (W4) and often issue form dropdown rules.
  2. Issue form required field empty (build_id, player_quote, fragment_id).
  3. Invalid labels array—typo or label not created on repo.
  4. Assignees/milestone IDs wrong for REST payload (less common than body).
  5. Body too large or contains characters breaking form JSON (rare vs invented repro).
  6. Template mismatch—API uses classic issue body while repo expects form-encoded field map.
  7. Human gate skipped (W5)—bot publishes before producer scrubs LLM draft.

Beginner path (first 30 minutes)

Prerequisites: gh CLI authenticated, transcript .txt for the clip, BUILD_RECEIPT.json with build_id, Whisper tag map preflight W1–W4 GREEN.

  1. Reproduce with gh issue create --dry-run using the failing title/body file.
  2. Read 422 JSON—note which field failed (player_quote, repro_verbatim, etc.).
  3. Replace body with quote-only template (Step 3 below)—max one verbatim quote block.
  4. Confirm build_id matches BUILD_RECEIPT jq output (W2).
  5. Retry dry-run → exit 0 → live create one issue → file receipt github_payload_ok: true.

Common mistake: Retrying the same LLM body with exponential backoff—422 is not transient.

Fastest safe fix path

Step 1 — Capture the 422 response (developer)

REST:

curl -sS -X POST \
  -H "Authorization: Bearer $GITHUB_TOKEN" \
  -H "Accept: application/vnd.github+json" \
  "https://api.github.com/repos/ORG/REPO/issues" \
  -d @/tmp/issue_payload.json | jq .

Note errors[] entries—often "field": "body" or form field IDs.

gh CLI:

gh issue create --title "Playtest P0 — fragment_03" \
  --body-file /tmp/issue_body.md \
  --label "P0-blocker" 2>&1 | tee /tmp/gh_422.log

Step 2 — Strip invented repro (W4 scrub)

Keep Remove
Verbatim quote from transcript “Steps to reproduce (AI)”
build_id from BUILD_RECEIPT Guessed GPU/driver steps
fragment_id (mkv filename) Merged timeline from wrong clip
“No — quote-only triage” “Probably click Options → …”

Cross-check quote substring:

QUOTE="I can't leave the tavern after the quest"
grep -F "$QUOTE" release-evidence/playtest/transcripts/fragment_03.txt

Fail grep → do not open issue; ask facilitator for clearer clip.

Step 3 — Quote-only body template (minimal 422-safe)

## Playtest VOD (quote-only)

**build_id:** `fest-demo-2026-10-rc3` (from BUILD_RECEIPT)
**fragment_id:** `fragment_03.mkv`
**repro_known:** No — quote-only triage

> "I can't leave the tavern after the quest — the door doesn't work."

Transcript sha256: `abc123…` (W1 receipt field)

For issue form repos, map fields to form IDs in gh issue create or use the web UI once to export the expected JSON shape from GitHub docs.

Step 4 — Validate labels and dry-run

# Labels must exist
gh label list | grep -F "P0-blocker"

# Dry-run (GitHub CLI 2.40+)
gh issue create --dry-run \
  --title "Playtest P0 — tavern soft lock (quote-only)" \
  --body-file /tmp/issue_body_quote_only.md \
  --label "P0-blocker"

Pass: exit 0, no 422 in output.

Step 5 — whisper_issue_tag_receipt_v1.json gate

{
  "schema": "whisper_issue_tag_receipt_v1",
  "build_id": "fest-demo-2026-10-rc3",
  "fragment_id": "fragment_03.mkv",
  "transcript_sha256": "abc123…",
  "gates": {
    "W4_repro_steps_invented_blocked": true,
    "W5_human_gate_before_api": true,
    "W6_github_payload_ok": true
  },
  "github_payload_ok": true,
  "github_issue_allowed": true,
  "issue_urls": [
    "https://github.com/ORG/REPO/issues/1842"
  ]
}

Pin under release-evidence/playtest/whisper-tags/WHISPER_ISSUE_TAG_RECEIPT.json.

Fail-closed jq:

jq -e '.github_payload_ok == true and .github_issue_allowed == true' \
  release-evidence/playtest/whisper-tags/WHISPER_ISSUE_TAG_RECEIPT.json

Pair Lesson 266 BUILD_RECEIPT promotion.

Verification

Check Pass when
Dry-run gh issue create --dry-run exit 0
Quote integrity Issue body substring ⊆ transcript file
BUILD_RECEIPT W2 build_id jq match
Live issue HTTP 201; URL in receipt issue_urls[]
Receipt github_payload_ok: true
BUILD_RECEIPT whisper_issue_tag_ok: true after promotion

Prevention

  1. Never pipe LLM output directly to GitHub API—draft tag map only (Guide W3–W5).
  2. Use issue forms with “No — quote-only triage” default for playtest template.
  3. CI: gh issue create --dry-run on PRs that touch triage scripts.
  4. Pre-create labels P0-blocker, P1-major, playtest, fest_public.
  5. Order receipts: concat_okloudness_spot_ok → Whisper → tag receipt (Audacity loudness evening).
  6. Separate crash symbolicate issues from playtest quote issues (Q4 diligence blog).

Developer branches

Branch A — Invalid label 422

gh label create "P0-blocker" --color "B60205" --description "Playtest blocker"

Remove unknown labels from payload; retry dry-run.

Branch B — Issue form field IDs

Export template from .github/ISSUE_TEMPLATE/playtest-quote-only.yml. Map API body to form fields or use gh issue create with template flag if supported on your CLI version.

Branch C — Rate limit vs 422

HTTP Meaning Action
422 Payload invalid Fix body/labels
403 + X-RateLimit-Remaining: 0 Rate limit Backoff
401 Bad token Refresh GITHUB_TOKEN

Do not backoff on 422.

Comparison — three triage failures

Symptom Lane Fix doc
No transcript file Concat / path MKV concat help
Whisper silent / clipped Loudness Audacity loudness preflight
422 on issue create Payload / invented repro This help

Related GamineAI reads

FAQ

Is 422 always invented repro?
No—check labels, assignees, and required form fields first. Invented repro is the most common cause in Whisper batch automation.

Can we disable issue forms for the bot?
Prefer quote-only forms over disabling—they prevent human facilitators from pasting bad repro too.

Does GitHub Copilot cause 422?
Copilot drafts in the web UI are human-reviewed; batch API failures come from unsupervised LLM bodies.

Same receipt as January batch?
No—january_whisper_batch_receipt_v1 owns batch order; whisper_issue_tag_receipt_v1 owns GitHub gate.

February live week same-day triage?
Pair February same-day Whisper strategy—422 fix applies before P0 issues hit pager stand-up.

Need Help when concat never completes?
Fix MKV concat first—no transcript means no quote to validate.


422 on playtest issue create is almost always a bad payload—scrub invented repro, dry-run gh issue create, file github_payload_ok on whisper_issue_tag_receipt_v1.json, then retry the API.