fix(oxbridge): install Chromium system libs on Railway + wait for images in PDF render - #2
Merged
Conversation
…ges in PDF render
Playwright was silently failing every PDF render because glib was missing
on the container. Text-only fallback stripped <img> tags, so teachers saw
lesson-plan text with no diagrams. This change:
1. Adds railpack.json declaring the Chromium runtime apt packages
(libglib2.0-0, libnss3, libgbm1, ...) so chromium.launch() no longer
exits 127 with "error while loading shared libraries". Also mirrors
the same list into nixpacks.toml as a fallback.
2. Switches htmlToPdf's page.setContent from waitUntil='domcontentloaded'
to 'networkidle' so remote <img> src fetches (e.g. S3-hosted lesson-plan
diagrams) resolve before the PDF snapshot. domcontentloaded returned
while images were still in flight, so page.pdf() captured unloaded
<img> nodes.
3. Promotes the swallowed catch in deliverOxbridgeLp from info-level to
level='error' so the next failure pages Axiom instead of hiding in
the noise floor.
Adds regression tests: the html-to-pdf suite asserts waitUntil='networkidle',
and a new oxbridge-lp-error-level test asserts the render/send catch logs at
error level.
hyasin270
pushed a commit
that referenced
this pull request
Sep 7, 2026
…ight Operator, 2026-09-07: "the reminders that teachers get that no one has attempted their quiz are annoying. Perhaps once after six hours is ok, but are we doing more than that?" Measured on production first. The nudge was ALREADY once per quiz — 118 events across 118 distinct quizzes, no duplicates. Three things were wrong anyway: 1. SIX HOURS, NOT THREE. NUDGE_AFTER_MS was 3h, which caught classes that simply had not got home yet. 2. QUIET HOURS, DEFERRED NOT DROPPED. The class report already pushes anything landing between 22:00 and 07:00 PKT to the morning; the nudge pushed nothing. Today's nudges by PKT hour ran 12:5 13:4 14:24 15:25 16:22 17:7 18:7 19:10 20:3 21:10 — ten teachers were told at 9pm or later that nobody had opened their quiz. Anything due 21:00-07:00 PKT is now held to 07:00 and still sent; the worker's existing re-queue loop waits it out. 3. ONE PER TEACHER PER DAY, NAMING THE QUIET LESSONS TOGETHER. It was once per QUIZ: 117 nudges reached 109 teachers, six got two and one got three, because teachers record up to four lessons a day. What that feels like is nagging, not a reminder about quiz #2. Now the first nudge of the day gathers the teacher's other quiet lessons, names them in ONE message, and stamps every one of them so none can nudge on its own later. New catalog string tqNudgeMany (en + ur) via resolveUx — no inline map, no ternary, no English floor. Red-first: tests/quiz/transcript-quiz-nudge-cadence.test.js, 12 cases, 10 of them failing before the change. Suites: root tests/quiz 1,975 pass (1 known pre-existing failure, flushShelf > deletes the shelf key, unrelated). Closes: bd-mg9c7.146 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> (cherry picked from commit f6ea63f)
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.
Summary
Oxbridge lesson-plan PDFs have been silently failing on the NIETE deployment for 48+ hours — teachers get text-only fallbacks with the
<img>tags stripped.Two root causes, both fixed here:
Chromium system libs missing on Railway — Playwright's bundled Chromium loads
libglib-2.0.so.0/libnss3/ etc. at runtime. Neitherrailpack.jsonnornixpacks.tomldeclared them, sochromium.launch()exited 127 on every call. This addsrailpack.jsonwith the full apt-package list Playwright's Chromium needs (mirroring the pattern our sibling PK bot uses successfully), plus the same list innixpacks.tomlas a fallback.waitUntil: 'domcontentloaded'returns before remote<img>src fetches settle — page.pdf() would then snapshot the DOM with unloaded image nodes. Switches to'networkidle'so S3-hosted lesson-plan diagrams actually render into the PDF.Also promotes the swallowed catch in
deliverOxbridgeLpfrom info-level tolevel='error'so the next silent failure pages Axiom instead of hiding in noise.Test plan
waitUntil: 'networkidle'in the html-to-pdf suite (fails before Fix 2, passes after)oxbridge-lp-error-level.test.jsasserting the swallowed catch emits atlevel='error'(fails before Fix 3, passes after)node --checkon both modified bot filesrequire('./bot/shared/utils/html-to-pdf.js')loads clean