Stop a bullet's open editor taking Studio down on the next keystroke - #108
Merged
Conversation
Opening a bullet's inline text editor and then typing anything threw on
every following rebuild:
RangeError (end): Invalid value: Not in inclusive range 0..8: -1
That aborts the Studio subtree mid-update, so the preview goes blank and
the error repeats every frame.
`VaultItemSelectorList.didUpdateWidget` closes an open editor when the
entry it belongs to leaves the CV, and recovered that entry by splitting
the editor's id on its last underscore. That holds for the two ids the
widget composes itself, `'<itemId>_title'` and `'<itemId>_<index>'`, but
the bullet sub-list passes a bullet's own bare id. A bullet id is a uuid,
or `exp-1-b1` in the worked example; neither contains an underscore, so
`lastIndexOf` returns -1 and `substring(0, -1)` throws. The 8 in the
message is `'exp-1-b1'.length`, so anyone on the example CV hits it
first.
Wrong twice over: had a bullet id happened to contain an underscore, the
split would have named an entry that does not exist and the editor would
have silently closed itself instead.
The owner is now carried alongside the id rather than parsed back out of
it, since only the call site knows which entry a row hangs off — and for
a bullet the id genuinely does not say.
Ported from IanHeinrich/CareerForge#46, where the same bug was reported
from production.
The PR template asks for a browser check on anything under lib/features/studio/widgets/, and the Studio preview pane was the thing that would not come up: it rasterizes build/web/pdfjs/pdf.min.mjs, the dev server's MIME table had no .mjs entry, and a module script served as application/octet-stream is rejected outright under strict MIME checking. The failure is silent from the app's side — the preview just spins for ever, with the only clue in the browser console — so it reads like the preview is broken rather than the server. Dev-only; GitHub Pages already types .mjs correctly.
IanHeinrich
added a commit
that referenced
this pull request
Aug 30, 2026
Ships the bullet inline-editor crash fix from #108, which landed on main without a version bump and so did not deploy. app_version.dart is regenerated from pubspec by build_version.
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.
What and why
Ported from IanHeinrich/CareerForge#46, where this was reported from production. cv-forge's copy of the code was character-identical, so it has the same bug.
Opening a bullet's inline text editor in Studio and then typing anything threw on every following rebuild:
That aborts the Studio subtree mid-update — the preview goes blank and the error repeats every frame.
VaultItemSelectorList.didUpdateWidgetcloses an open editor when the entry it belongs to leaves the CV, and recovered that entry by splitting the editor's id on its last underscore. That holds for the two ids the widget composes itself —'<itemId>_title'and'<itemId>_<index>'— but the bullet sub-list passes a bullet's own bare id. A bullet id is a uuid, orexp-1-b1in the worked example; neither contains an underscore, solastIndexOfreturns-1andsubstring(0, -1)throws. The8in the message is'exp-1-b1'.length— anyone on the example CV hits it first.Wrong twice over: had a bullet id happened to contain an underscore, the split would have named an entry that does not exist and the editor would have silently closed itself instead.
The owner is now carried alongside the id rather than parsed back out of it (
typedef _OpenEditor = ({String id, String ownerId})), since only the call site knows which entry a row hangs off — and for a bullet the id genuinely does not say. The three call sites each bind their own owner; the string surgery is gone.The second commit is unrelated to the bug and dev-only: the Studio preview would not come up locally at all, because it rasterizes
build/web/pdfjs/pdf.min.mjsandtool/serve_web.mjs's MIME table had no.mjsentry — a module script served asapplication/octet-streamis rejected under strict MIME checking, so the preview spins for ever with the only clue in the browser console. That blocked the browser check this template asks for. Pages already types.mjscorrectly.How it was verified
dart format --output=none --set-exit-if-changed .flutter analyze— no issues foundflutter test --exclude-tags=golden— 888 passlib/features/studio/widgets/)The new test reproduces the production error against the pre-fix code exactly:
0..8: -1for the fixture id and0..36: -1for a uuid.Browser check, on the example CV: Studio → Work history → expand a bullet sub-list → open a bullet's inline editor → type. The editor stays open, the text takes, the count moves to "tailored", the PDF preview stays rendered, and the console carries no
RangeError.Goldens
Anything else
Two things from the upstream PR were deliberately left out as CareerForge-specific: the
0.0.10 → 0.0.11version bump — cv-forge is on 2.24.0 andbackup_service.dartreadspackageVersionrather than a duplicated literal, so there is nothing to keep in sync — and thedocs/roadmap.mdentry. Say the word if a release bump is wanted here.