fix(watchers): malformed array literal swallows chat replies#994
Conversation
resolveWatcherRunsByMessageIds passed a raw JS array as `${ids}::text[]`.
The bundled postgres.js serializes that as a bare scalar (the message UUID),
so Postgres rejects it: malformed array literal: "<uuid>". This throws on
every terminal chat payload (api-response-renderer 'Failed to resolve watcher
runs from terminal API payload'), intermittently swallowing the final CLI
render. Wrap with pgTextArray(ids) to match the canonical
ANY(${pg*Array(...)}::type[]) pattern used at every other call site.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe PR updates ChangesPostgres Array Binding Refactor
Possibly related PRs
Poem
🎯 1 (Trivial) | ⏱️ ~3 minutes 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint skipped: no ESLint configuration detected in root package.json. To enable, add Comment |
|
bug_free 86, simplicity 100, slop 0, bugs 0, 0 blockers Typecheck/unit passed. [env] Integration failed because harness refused database "postgres" as non-test DB, unrelated to changed watcher file. Explored pgTextArray via bun -e for representative ids/escaping; no live DB probe because DATABASE_URL/psql unavailable. DB-only query holds with 3 replicas. Full verdict JSON{
"bug_free_confidence": 86,
"bugs": 0,
"slop": 0,
"simplicity": 100,
"blockers": [],
"change_type": "fix",
"behavior_change_risk": "low",
"tests_adequate": false,
"suggested_fixes": [],
"notes": "Typecheck/unit passed. [env] Integration failed because harness refused database \"postgres\" as non-test DB, unrelated to changed watcher file. Explored pgTextArray via bun -e for representative ids/escaping; no live DB probe because DATABASE_URL/psql unavailable. DB-only query holds with 3 replicas.",
"categories": {
"src": 4,
"tests": 0,
"docs": 0,
"config": 0,
"deps": 0,
"migrations": 0,
"ci": 0,
"generated": 0
}
}Local review gate — branch protection can require the |
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Problem
resolveWatcherRunsByMessageIds(run on every terminal chat payload byapi-response-renderer) builtdispatched_message_id = ANY(${ids}::text[])from a raw JS array. The bundledpostgres.jsserializes that parameter as a bare scalar (the message UUID), so Postgres rejects it:Because it throws in the response-render path, it intermittently swallows the final CLI render of an otherwise-successful chat. Every other call site in the codebase uses the canonical
ANY(${pg*Array(...)}::type[])(string-literal helper + cast); this was the lone raw-array usage.Fix
Wrap
idswithpgTextArray(ids)(already exported fromdb/client.ts), matchingrunStatusLiteral/pgBigintArrayusage everywhere else. 2-line change.Reproducer (red → green, real bundled server, embedded Postgres)
mainbuild): alobu chatturn logsmalformed array literal: "<uuid>"+Failed to resolve watcher runs from terminal API payload(Postgres22P02).Session completed successfully - all content already streamed.Note: a standalone
postgres.jsrepro did not reproduce it (it serialized the JS array correctly) — the bug only manifests through the esbuild-bundled server, which is why the E2E was run against the actuallobu runbuild.Summary by CodeRabbit