OPER-208
Fix CreateTask 500 on full-payload POST (retire narrow-POST-then-PATCH workaround)
Suggested
Justin Cooke
Body
---
feature_id: FEAT-studio-planning-validation
---
## Context
Every ticket-filing session for the past three weeks (2026.08.26, 2026.09.08, 2026.09.10, 2026.09.13) has used a narrow-POST-then-PATCH workaround: POST with only `{title, body, priority}`, then PATCH `{size, module, writeSets, verificationCmd}`. The reason: POST with the full payload returns HTTP 500 with an opaque error.
This has cost roughly 2 extra API calls per ticket + additional latency on every filing session. Total waste at ~20 tickets/week: 40 extra calls/week for weeks.
Root cause hypothesis (unverified until this ticket ships): the POST handler at `apps/web/src/app/api/studio/[team]/tasks/route.ts` runs classification/planner logic in the same transaction as the create, and the classifier fails on partial input, cascading to a 500 that swallows the classifier error. The PATCH path succeeds because classifier does not re-run on PATCH.
## What
Diagnose and fix the POST-500-on-full-payload path. Three-step:
1. **Reproduce**: write a failing integration test at `apps/web/src/app/api/studio/[team]/tasks/route.test.ts` that POSTs `{title, body, priority, size, module, writeSets, verificationCmd}` and asserts HTTP 201.
2. **Diagnose**: capture the 500 stack trace via a temporary Sentry-style trace + log the classifier input at time of failure.
3. **Fix**: either (a) make the classifier resilient to fully-populated intake, or (b) separate the create-then-classify path into two sequential transactions in the handler with the classifier failure NOT rolling back the create. Prefer (b) — the ticket should always land even if classifier fails; classifier can retry async.
Add regression test that asserts POST with the full payload returns 201, is admitted, and (if band-classifiable) is classified within one tick.
## Acceptance Criteria
- [ ] Failing integration test reproduces the 500 in CI
- [ ] Root cause identified and documented in the ticket comment thread
- [ ] Fix lands (either classifier resilience or create-then-classify separation)
- [ ] Regression test asserts POST with full payload returns 201
- [ ] Regression test asserts classifier still fires within one tick when payload is full
- [ ] Documentation update: `docs/task-state-machine.md` notes the fix and removes the narrow-POST-then-PATCH workaround guidance
## Blocked-by
None.
## Size / Band
M / assurance (touches POST handler, classifier, adds regression tests; potentially touches transaction boundary — the reason it is M and not S is the diagnosis unknown-cost).
## Discovered by
Weekly filing workaround since at least 2026.08.26. Documented in session summary 2026.09.10 as `CreateTaskBody-500-On-Full-Payload` failure class candidate. Not filed until 2026.09.13.
## Verification
Ships when full-payload POST works and the workaround is removed from ticket-filing scripts, and the regression test guards it.
Attachments
Loading attachments…
Comments
Loading comments…