The map goes blank when "Add a marker" is pressed #1251

Closed
opened 2026-10-28 00:17:04 +00:00 by claude-bot · 2 comments
Collaborator

Seen on prod (4.6.0), 2026-10-28. A map draws normally; pressing Add a marker turns the canvas blank (zoom buttons left, unstyled). Clicking still places a marker, but nothing is visible to aim at, and the map stays blank after Cancel until a reload.

Cause. MapCanvas.jsx rendered the Leaflet container's className as qmap__canvas${placing ? " qmap__canvas--placing" : ""}. Leaflet adds its own classes to that same element (leaflet-container, leaflet-touch, leaflet-grab…). When placing flips, React rewrites the attribute and wipes them. Without .leaflet-container, Leaflet's img.leaflet-tile { max-width: none } override no longer applies, and the global img { max-width: 100% } shrinks every tile to the zero-width tile container's width: nothing is drawn.

Fix. Keep the rendered className constant and toggle qmap__canvas--placing with classList in an effect. A regression test in MapCanvas.test.jsx re-renders with placing true and false and asserts leaflet-container survives (fails on the old code).

Seen alongside, not the cause: one uvicorn worker process died at 00:08:31 during the first tile burst for the 4096² map (66 tiles 502'd, "upstream prematurely closed connection"); the backend container has a 512 MiB limit. Noted here and worth a separate look if it recurs.

**Seen on prod (4.6.0), 2026-10-28.** A map draws normally; pressing *Add a marker* turns the canvas blank (zoom buttons left, unstyled). Clicking still places a marker, but nothing is visible to aim at, and the map stays blank after Cancel until a reload. **Cause.** `MapCanvas.jsx` rendered the Leaflet container's `className` as `qmap__canvas${placing ? " qmap__canvas--placing" : ""}`. Leaflet adds its own classes to that same element (`leaflet-container`, `leaflet-touch`, `leaflet-grab`…). When `placing` flips, React rewrites the attribute and wipes them. Without `.leaflet-container`, Leaflet's `img.leaflet-tile { max-width: none }` override no longer applies, and the global `img { max-width: 100% }` shrinks every tile to the zero-width tile container's width: nothing is drawn. **Fix.** Keep the rendered className constant and toggle `qmap__canvas--placing` with `classList` in an effect. A regression test in `MapCanvas.test.jsx` re-renders with `placing` true and false and asserts `leaflet-container` survives (fails on the old code). **Seen alongside, not the cause:** one uvicorn worker process died at 00:08:31 during the first tile burst for the 4096² map (66 tiles 502'd, "upstream prematurely closed connection"); the backend container has a 512 MiB limit. Noted here and worth a separate look if it recurs.
Author
Collaborator

On the worker death noted above: the owner remembers it as happening around the upload, with the tiles taking a long time to come in. The prod logs put it just after the upload:

  • 00:08:09 POST .../maps/5adeaf63…/image returned 200, so the upload itself succeeded.
  • 00:08:19 onward, the browser requested every zoom-0 tile (256 for a 4096² map opened fit-to-frame), spread over about ten seconds.
  • About 00:08:31 a uvicorn child process died, and 66 tile requests got a 502. Those tiles stay blank until the page is reloaded, because Leaflet does not retry a failed tile. The container itself did not restart (RestartCount 0, OOMKilled false), and the kernel log was not checked, so the cause is unconfirmed.

Follow-up worth considering if it recurs: cut downsampled levels as well as zoom 0, so a map that opens zoomed out loads a handful of tiles instead of all of them. #1253 documents the current behaviour for GMs.

On the worker death noted above: the owner remembers it as happening around the upload, with the tiles taking a long time to come in. The prod logs put it just after the upload: - 00:08:09 `POST .../maps/5adeaf63…/image` returned 200, so the upload itself succeeded. - 00:08:19 onward, the browser requested every zoom-0 tile (256 for a 4096² map opened fit-to-frame), spread over about ten seconds. - About 00:08:31 a uvicorn child process died, and 66 tile requests got a 502. Those tiles stay blank until the page is reloaded, because Leaflet does not retry a failed tile. The container itself did not restart (RestartCount 0, OOMKilled false), and the kernel log was not checked, so the cause is unconfirmed. Follow-up worth considering if it recurs: cut downsampled levels as well as zoom 0, so a map that opens zoomed out loads a handful of tiles instead of all of them. #1253 documents the current behaviour for GMs.
Author
Collaborator

Fixed in PR #1252 (squash-merged as e26a0ad4), with a regression test that fails on the old code. Ships in v4.6.1.

  • v4.6.1-rc1 was tagged at 129d5582, the release build passed, and the three images exist.
  • Deployed to dev 2026-10-28 06:26 UTC after a backup (questboard_manual_20261028T062555Z.dump). No migrations. All seven services are healthy, /ready is ok, /api/meta reports 4.6.1-rc1, and there were no errors in the logs.
  • The built map chunk on dev (Map-BW-lpOiI.js) carries the classList.toggle("qmap__canvas--placing", …) fix. It wasn't clicked through on dev, which has real users and needs a real login.

Prod stays on 4.6.0 until the owner says to deploy 4.6.1.

Fixed in PR #1252 (squash-merged as e26a0ad4), with a regression test that fails on the old code. Ships in **v4.6.1**. - `v4.6.1-rc1` was tagged at 129d5582, the release build passed, and the three images exist. - Deployed to **dev** 2026-10-28 06:26 UTC after a backup (`questboard_manual_20261028T062555Z.dump`). No migrations. All seven services are healthy, `/ready` is ok, `/api/meta` reports 4.6.1-rc1, and there were no errors in the logs. - The built map chunk on dev (`Map-BW-lpOiI.js`) carries the `classList.toggle("qmap__canvas--placing", …)` fix. It wasn't clicked through on dev, which has real users and needs a real login. Prod stays on 4.6.0 until the owner says to deploy 4.6.1.
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rbrooks/Quest-Board#1251
No description provided.