Tracker: bug reports from the field #33
Description
Activity
SVG export opens blank in Inkscape (Discord, Lski3, 2026-08-26)
Symptom: exported SVG is completely blank in Inkscape, fine in browsers. Reporter also found a
data:text/html;base64,...(GitHub Pages 404 page) embedded as theoceanicPatternimage.Diagnosed — two independent defects, both reproduced locally:
-
Blanker (root cause): global Style filters (Tint etc.) are applied as
filter="url(#filter-tint)"on the root<svg id="map">and exported verbatim. Inkscape (verified on 1.4.4) renders any real exported document with a filter on the root svg element as fully blank. Verified fix direction: at SVG export time, move the filter attribute from the root onto the#viewboxgroup — full map then renders in Inkscape with the tint applied, and browsers render it identically. Masks are NOT the cause (Azgaar's guess) — exports render fine in Inkscape 1.4.4 once the root filter moves. -
Cosmetic:
getBase64(src/utils/commonUtils.ts:146) inlines whatever the ocean-pattern URL returns with no status/content-type check, so a 404 HTML page gets embedded as the image. Confirmed:azgaar.github.io/images/pattern1.png→ GitHub 404 page matching the reporter's decoded base64. Fix: only inline 2xx + image/* responses.
Full diagnosis with repro method:
docs/superpowers/specs/2026-08-26-svg-export-inkscape-blank.md(uncommitted on feat/marker-icon-svg-defaults working tree). Both defects exist upstream too (modules/io/export.js) — upstream-worthy fixes, target TBD.-
Update: fix implemented on branch
fix/svg-export-inkscape(commit 8a029db, local only — not yet pushed/PR'd).Implementation revealed the relocation alone is insufficient: with default filter regions Inkscape miscomposites the big filtered group racily (same file flips between clean, blank, and black-blob renders across repeated opens — its multithreaded filter renderer). Final fix = relocate root filter to
#viewbox+ explicitfilterUnits=userSpaceOnUse x=0 y=0 width=100% height=100%on every filter def at export time. Measured: 0% usable before → 15/16 and 5/5 clean renders on the two pathological test maps; residual ~5% is Inkscape-internal and fixed by re-opening the file.getBase64now refuses non-2xx/non-image responses and the export drops the pattern/texture image instead of embedding error pages (a dead href renders as a dark broken-tile grid in Inkscape).7 new unit tests; full suites green fork (778) and upstream port (428 — upstream master is already on the src/ layout, port is near-1:1, held locally pending go-ahead). Spec updated:
docs/superpowers/specs/2026-08-26-svg-export-inkscape-blank.md.Landed as PRs: fork #43 (base main) and upstream Azgaar#1646 (base
1.149.0, rebased onto that version branch — only merge delta was coexisting with the newparseErrortests incommonUtils.test.ts). Both verified green on their respective bases (fork 778 tests, upstream 437).Second Inkscape defect found via field testing (user's own Inkscape session): map icons render hundreds of times too large — giant black blobs covering the map. Cause: burg/anchor/goods/relief icons are
use→symbolreferences sized by the symbol's1emwidth against the group font-size; Inkscape can't resolve that and falls back to viewport-sized icons. "No Filters" display mode doesn't help (it's not the filter bug).Fix pushed to both PRs (fork #43 commit 3d5d998, upstream Azgaar#1646 commit 924c08f):
flattenSymbolReferencesat SVG export bakes the viewBox math into atransformperuseand converts symbols to plain groups — no symbol sizing semantics left for any renderer to get wrong. Also dedupes the per-burg-group symbol defs (duplicate ids). 8 new unit tests (em sizing incl. inlinedfont:shorthand, explicit use w/h, viewBox min offsets, meet centering); Inkscape 3/3 identical clean renders with correct icon sizes; Chromium unchanged.Note on sequencing: #43 merged before the icon-scaling fix was pushed, so fork
maincurrently has only the filter/getBase64 half. The icon flattener is now up as #44 (single commit3d5d998con top of merged main). Upstream Azgaar#1646 carries both halves in one PR.New report — 2026-08-30, Discord (volley), Electron desktop client v1.149.1.
getting this error any time i want to add a note to something. electron client v1.149.1 [...] doesn't seem to affect anything functionally but it's an annoying popup
Adding a note to any object raises the "New version released" dialog ("This part of the app failed to load because a new version was released while the page was open"). Purely cosmetic — the note editor works.
Diagnosis:
onChunkLoadErrorinsrc/services/app-shell.tslistens forvite:preloadErrorand unconditionally offers a reload. That assumption ("a release replaced the content-hashed chunks on the server") is only true for the hosted web build; in the packaged desktop app the chunks ship with the bundle, so the modulepreload of the notes-editor chunk fails under the Electron file/app protocol while the dynamicimport()still succeeds.Suggested fix: gate the dialog on an http(s) origin, or confirm the import actually failed before offering a reload.
Reported upstream: Azgaar#1660 (screenshot attached there). Affects the fork identically — same file, same listener.
New report — 2026-09-03, Discord (DietCholera), map
The Flames, originally saved on 1.139.4, loaded on 1.150.0.Symptom: "labels missing", plus the
labels,emblems,tradeandthreeDoption sections absent from the.map. The file was never damaged; keys that post-date the file's version are synthesised by migration. Two independent bugs were in play, which is what made it look like corruption:- Loaded old maps: burg tiers hidden at every zoom — 1.140 migration bakes transient zoom
display: noneinto persisted label group styles Azgaar/Fantasy-Map-Generator#1773. The 1.140 migration harvested the legacy zoom auto-visibilitydisplay: nonefrom each tier'sstyleattribute into the persisted label group style. Since 1.150 the styles store is applied over the saved svg on load, so clearing the DOM and re-saving does not help; the stored string has to be cleaned. Fix: stripdisplayin the harvest funnel and add a 1.151.2 migration pass over stored label group styles. Fork fix: strip zoom auto-visibility display from migrated label group styles #66 merged (da86d21, fork main now 1.151.2-fork.1); upstream fix: strip zoom auto-visibility display from migrated label group styles Azgaar/Fantasy-Map-Generator#1802 open. Verified on the reporter's original file and the 1.150.0 re-save against an unfixed baseline. - New maps: zero labels in that browser — Stale localStorage
options-labelssilently removes labels from all newly generated maps Azgaar/Fantasy-Map-Generator#1771. StalelocalStorage["options-labels"]is seeded intooptionsunvalidated, at boot and again inrandomizeOptions(). Fix upstream as fix: validate the stored label and burg group registries Azgaar/Fantasy-Map-Generator#1801 (open); no fork PR yet. User workaround: Label Groups editor → Restore, or DevTools → Application → Clear site data.
The two PRs touch different structures and were load-tested together on both of the reporter's files. Tables updated.
- Loaded old maps: burg tiers hidden at every zoom — 1.140 migration bakes transient zoom
Grid layer missing from image/SVG export (reported 2026-09-09)
Report: users say the grid overlay is not included in exported images even when the layer is visible, and want it to be.
Diagnosis: real bug, present on fork
mainand on Azgaarmaster. The grid is meant to be exported (the export path explicitly copies the grid pattern into the export defs), but the copy step never fires.Root cause: the style migration (Azgaar Azgaar#1644, v1.150.0) moved the grid type from a
typeattribute on#gridOverlayintostyles.grid.options.type.drawGrid(src/renderers/draw-grid.ts) now reads the store and no longer writes the attribute, butgetMapURLinsrc/services/io/export.tsstill readsgridOverlay.getAttribute("type"), getsnull, looks up#pattern_null, finds nothing, and so the<pattern>never reaches the exported<defs>. The exported rect keepsfill="url(#pattern_pointyHex)", which resolves to nothing and renders as empty. PNG, JPEG and SVG exports all go through the same clone, so all three are affected.Maps saved before v1.150.0 still carry the old
typeattribute in their SVG, so they export fine. New maps and maps re-saved after the migration lose the grid. That matches "some users see it, some don't".Headless reproduction (fresh map, grid layer on,
Services.ExportMap.getMapURL("svg", {fullMap: true})):storeType: "pointyHex" liveTypeAttr: null exportedRectFill: "url(#pattern_pointyHex)" exportedDefsHasPattern: false exportedPatternIds: ["oceanic"]Fix candidate: in
export.ts, resolve the pattern fromstyles.grid.options.type || "pointyHex"instead of the DOM attribute (mirrorsdrawGrid). One-line change, no fix written yet. Should go upstream as well.Status: Open, awaiting decision on fork-only vs upstream PR.
Grid-in-export fix opened upstream as Azgaar#1826 (branch
fix/grid-export-pattern, commit 664cc65, e2e test included). Fork side: lands with the next upstream sync; no separate fork PR.New field report 2026-09-11 (Discord): Diplomacy editor shows "Invalid" after removing a state; Regenerate stops working.
Root cause:
States.generateDiplomacy()vassal-copy loops (states-generator.ts, "Vassals copy relations from their Suzerains") iteratei/eover every state index with noremovedguard. A removed state is stored as{i, removed: true}with nodiplomacyarray, so the first vassal processed throwsTypeErrorreadingstates[removed].diplomacy[suzerain]. Generation aborts mid-way, leaving every row from the first vassal onward as thexplaceholder; upstream Azgaar#1846 renders those as "Invalid" (the fork, without Azgaar#1846, would crash the editor render instead).Confirmed against the reporter's map to the index: state 1 removed, first vassal is state 24, rows 2–23 complete, 24+ all
xfrom index 24 up.Needs: removed state + at least one vassal generated in that run. Fix shape: skip
removedstates in the inner loops (also theneibOfNeibneighbour lookup). Present in both upstream master and the fork. No fix written yet.Status: Open / awaiting reporter console output. Diagnosis:
docs/superpowers/specs/2026-09-11-diplomacy-invalid-after-state-removal.md.Diplomacy "Invalid" after state removal: fix written, Azgaar PR Azgaar#1854 open (branch
fix/diplomacy-removed-stateon the fork, commit 7d29bb5). Fork gets it via the next upstream sync. Status: Fixed upstream, PR pending.New field report 2026-09-11 (Azgaar Azgaar#1853): Anchor Icon size shows 1 and edits are lost on reload.
Root cause: the map's style record has
burgIcons.anchors.groups = {}while the saved SVG still carriesfont-size18/12/8 on#anchors > g. On load the empty record is accepted, nothing seeds anchor entries (ensureBurgGroupStylesneeds an existing template), the renderer emits nofont-size, and the style editor'sif (group)guard drops every size edit — so save round-trips{}.Origin: pre-1.150
main.jsinitialised the legacy style asanchors: {}; the 1.150 migration treats{}as a present record (if (legacy.anchors)), stores it empty, and skips the SVG harvest (hasStyleRecord: true). Generic, upstream master has it. Second partial route: the 1.145 dedupe deleting empty custom anchor groups (already in memory).Fix shape: treat empty legacy records as absent in the migration; on load, harvest empty icon/anchor groups from the restored SVG (recovers the reporter's sizes) and seed defaults otherwise; template fallback in
ensureBurgGroupStyles. No code yet.Status: Open — diagnosed, awaiting go-ahead for the fix. Diagnosis:
docs/superpowers/specs/2026-09-11-anchor-icon-size-not-saved.md.Anchor icon size (Azgaar Azgaar#1853): fix written, Azgaar PR Azgaar#1855 open (branch
fix/empty-burg-group-styleson the fork, commit 20c18a9). Verified headless against the reporter's map: anchor groups restored to 18/12/8 from the saved SVG. Fork gets it via the next upstream sync. Status: Fixed upstream, PR pending.
Running log of user-reported bugs, their diagnosis, and where the fix landed. One comment per new report; edit the tables as status changes.
Fixed
The Flames, saved on 1.139.4)display: nonefrom each burg tier'sstyleattribute into the persisted label group style; the 1.150 store migration kept it, and the store is applied over the saved svg on load, so re-saving never sheds it. Upstream issue Azgaar#1773displayin the harvest funnel (labelStyleFromLegacy) plus a 1.151.2 migration pass over the stored label group styles for maps saved by 1.150-1.151.1. Fork #66; upstream Azgaar#1802Open / awaiting info
onChunkLoadError(src/services/app-shell.ts) shows the reload dialog on anyvite:preloadError. That assumption only holds for the hosted web build — in the packaged desktop app every chunk ships with the bundle, so the modulepreload of the notes-editor chunk fails under the Electron protocol while theimport()itself succeedslocalStorage["options-labels"](andburg-groups) is seeded intooptionsunvalidated at boot and again inrandomizeOptions(); a stale{groups: []}from an earlier build empties the label group registry. Upstream issue Azgaar#1771Closed — not a bug
Related knowledge
display: noneinto persisted label group styles Azgaar/Fantasy-Map-Generator#1773 / Stale localStorageoptions-labelssilently removes labels from all newly generated maps Azgaar/Fantasy-Map-Generator#1771 — the two halves of the 2026-09-03 "labels missing" report; the file was never damaged, the missinglabels/emblems/trade/threeDoption keys in an old file are synthesised by migration