M-L1-T3d: JSON.stringify body in fetch-ai httpClient (RED spec)#129
Merged
Conversation
…y object body Production bug discovered 2026-05-03 16:39 UTC after PR #126 (T-3c schema) merged: fetch-ai crawl returns processed:0 with durationMs:90 — adapter runs but yields zero records. Root cause: wiring's httpClient.fetch wrapper for fetch-ai passes body as JS object directly to Node's native fetch: fetch: async ({ url, method, body, headers }) => { const r = await fetch(url, { method, body, headers }); // ← body is JS object ... } Node fetch coerces non-string non-Buffer body via String() → "[object Object]" → Agentverse rejects with 400 (or returns empty parsed body) → adapter's defensive try/catch swallows result silently → processed:0. This is the 4th iteration on fetch-ai. PRs #120 (adapter) #124 (wiring inject) #125 (POST method) #126 (schema rewrite) each fixed one layer. T-3d closes the wire-format layer. RED test: 1 new test in tests/wiring-rest-adapter-httpclient.test.ts asserts that when adapter calls httpClient.fetch with object body, the underlying native fetch receives a JSON string (not an object). Vitest output: 1 failed (T-3d), 4 passed (existing). Fix is 1-line in wiring/01-registry.cjs — slim spec for backend-dev in docs/sprints/M-L1-T3d-body-stringify.md.
|
The latest updates on your projects. Learn more about Vercel for GitHub. 8 Skipped Deployments
|
Contributor
Author
Phase 0 SPEC APPROVED (architect self-call sub-agent)Verdict: SPEC APPROVED.
Backend-dev ready to pick up. Expected outcome: 5/5 wiring tests GREEN + production smoke processed>0. 🤖 Phase 0 reviewer (sub-agent self-call by architect) |
Production bug after PR #126: adapter passes object body to wiring's httpClient.fetch; wrapper passed it as-is to native fetch; Node coerces object via String() → "[object Object]" → Agentverse rejects → adapter silent processed:0. Fix: serialize body to JSON string when it is an object before native fetch. String/Buffer bodies pass through unchanged. 5/5 wiring tests GREEN.
Type 1 task — unit tests cover full contract; this acceptance is thin wrapper for quality-gate.sh step 6/6 (test-runner reported missing acceptance). 5 checks: 1. wiring calls JSON.stringify(body) 2. conditional typeof === 'object' (preserves string/Buffer) 3. native fetch receives serializedBody, not raw object 4. RED test still asserts JSON-string contract 5. vitest 5/5 GREEN Local run: PASS=5 FAIL=0.
a3ka
pushed a commit
that referenced
this pull request
May 7, 2026
Phase N review verdict: APPROVED. 3-commit chain on feature/M-L1-T3d-body-stringify (architect RED + backend-dev cherry-pick fix + architect acceptance). Closes 4th and final pipeline-layer bug on M-L1 fetch-ai crawler: wiring's httpClient.fetch wrapper passed body as raw JS object to Node's native fetch, which coerced via String(obj) → "[object Object]" → Agentverse 400 → silent processed:0. Surgical 8-line conditional JSON.stringify only when typeof body === 'object', preserves string/Buffer pass-through, mcp + paxio-curated branches unchanged. Quality gate: 7/7 GREEN (typecheck + node-check + vitest 1436/1436 + acceptance 5/5 + governance). Scope clean per commit, identity matches scope-guard table, TESTS SACRED honored (backend-dev didn't touch tests), conventional commits, production smoke ready (next 6h cron tick should yield processed > 0 with ~10K agents). Zero P0/P1/P2 blockers, zero new TD entries. Ready for architect gate-1 merge per workflow.md::feature/* → dev autonomous gate.
a3ka
pushed a commit
that referenced
this pull request
May 7, 2026
Production bug after PR #129 merge: fetch-ai crawl returned 9226 storageErrors / 0 upserted. Root cause: pg CHECK constraints on new taxonomy columns reject NULL; adapter doesn't populate these (Zod-optional); upsertParams used `?? undefined` → pg coerced to NULL → CHECK violation on every insert. Fix: emit SQL-DEFAULT-matching enum values for CHECK-constrained columns: framework='unknown', wallet_status='none', payment_facilitator='unknown', security_badge_level='none'. Replace remaining `?? undefined` with `?? null` for non-enum fields. 28/28 postgres-storage tests GREEN.
a3ka
pushed a commit
that referenced
this pull request
May 7, 2026
Phase N review — APPROVED, no must-fix, no TD entries. 5th iteration on M-L1 fetch-ai pipeline closes the storage CHECK-violation layer. After PR #129 (body-stringify) restored adapter to ~9226 records, all 9226 hit storage.upsert() and pg rejected each with CHECK violation on framework/wallet_status/payment_facilitator/security_badge_level columns (?? undefined → NULL → CHECK fail). Fix: emit SQL-DEFAULT-matching enum strings ('unknown'/'none') at positions \$18/\$21/\$26/\$39 + replace remaining `?? undefined` with `?? null` (pg 8.x deprecates undefined params). 2-commit chain on clean base (b6768f8): - 2fa4b85 architect — RED spec (1 test + slim spec + acceptance) - 00ee0cc registry-dev — impl (1 file, 22-line edit) Reviewer worktree validation (identity=reviewer): - pnpm typecheck: 0 errors - pnpm exec vitest run: 1454 passed | 16 skipped | 5 todo (full baseline) - postgres-storage.test.ts target: 28/28 GREEN - bash scripts/verify_M-L1-T3e-storage-defaults.sh: PASS=7 FAIL=0 - quality-gate.sh per test-runner report: 7/7 GREEN - git status clean - per-commit identity matches scope-guard table - tests SACRED honored (registry-dev touched 0 test files) Standards walk: - P0 clean (no multi-tenancy break, no SQL injection, no any/cast) - P1 clean (factory frozen, domain purity preserved, AppError untouched, conventional commits, tests sacred) - P2 clean (rationale comments, consistent return shape, no dead code) Note: acceptance script step 2 has cosmetic glitch (echoes literal `??` producing benign `line 26: ??: command not found` warning); does NOT affect PASS counter; architect-owned P2 cosmetic. → architect merges PR #131 → dev per workflow.md gate-1 autonomous.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Production bug 2026-05-03 16:39 UTC after PR #126 (T-3c schema) merged. Fetch-ai crawl:
processed:0, durationMs:90— adapter runs but yields zero records.Root cause: wiring's httpClient.fetch wrapper passes body as JS object to Node's native fetch. Node coerces non-string body via String() → `"[object Object]"` → Agentverse rejects → silent zero.
This is the 4th iteration on fetch-ai (PRs #120 adapter, #124 wiring inject, #125 POST method, #126 schema rewrite, this PR closes wire-format layer).
Changes
tests/wiring-rest-adapter-httpclient.test.ts— 1 new RED test asserting native fetch receives JSON string bodydocs/sprints/M-L1-T3d-body-stringify.md— milestone + slim spec for backend-devГотово когда
processed > 0, ~10K agents from AgentverseCurrently
RED 1/5 (T-3d test fails on
expect(typeof capturedInit.body).toBe('string')). 1-line fix in01-registry.cjsper slim spec.🤖 Generated with Claude Code