Skip to content

fix(library-server): highlights import and sync fail on Postgres (JSON parameter sent as a string) - #46

Merged
sawradip merged 1 commit into
mainfrom
fix/highlights-jsonb
Nov 1, 2026
Merged

sawradip merged 1 commit into
mainfrom
fix/highlights-jsonb

Conversation

@sawradip

@sawradip sawradip commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

What broke: the first highlights:move --go into the production library (deployed with #44 via #45) failed with cannot call jsonb_to_recordset on a non-array, and the server answered 500. Nothing was written: each request is one transaction, and the library still has no lines or links.

Why: for a $n::jsonb parameter, postgres.js (the production driver) encodes the JSON text again, so Postgres received a JSON string instead of the array. PGlite, which the tests used, passes the text through unchanged, so the tests did not catch it. This affects lines/sync and import, the two routes that send many rows at once.

Fix:

  • The four jsonb_to_recordset($2::jsonb) become jsonb_to_recordset($2::text::jsonb).
  • highlights.test.ts also runs on a real Postgres when TEST_POSTGRES_URL is set.
  • CI gets a Postgres service and runs the highlights tests on it.

Checked:

  • On local Postgres 18, without the fix 14 of 16 highlights tests fail; with it, all 16 pass. They pass on PGlite too.
  • End to end: a local server on Postgres, with ChalkBook's real data copied in (6,310 lines, 9,389 links). The copy is identical to the source, and all 285 pages give the same counts as the database.
  • pnpm check passes.

After merging, a release PR into prod deploys it.

🤖 Generated with Claude Code

…xt (postgres.js sent them as a JSON string); tests and CI on a real Postgres

The import failed in production with "cannot call jsonb_to_recordset on a non-array": for a $n::jsonb parameter postgres.js
encodes the JSON text again, so Postgres got a JSON string instead of the array. Casting through text ($n::text::jsonb) sends it
as it is. PGlite, which the tests used, passes it unchanged, so they did not show it: TEST_POSTGRES_URL runs them on a real
Postgres (14 of 16 fail there without this fix), and CI does so with a Postgres service.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sawradip

sawradip commented Nov 1, 2026

Copy link
Copy Markdown
Contributor Author

Codex review — round 1 (fast) (Codex CLI's output, posted here via gh from my account)

STATUS: LGTM
FINDINGS: (none)

It also checked the other array parameters ($n::uuid[], $n::int[], $n::text[] with JS arrays) and found them encoded correctly by postgres.js. The end-to-end run on a real Postgres in the PR description exercises them too.

@sawradip
sawradip merged commit df615a6 into main Nov 1, 2026
1 check passed
sawradip added a commit that referenced this pull request Nov 1, 2026
Deploy the library server: highlights import and sync on Postgres (#46)
@sawradip sawradip mentioned this pull request Nov 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant