fix(migrate): ctx codemod no longer rewrites inside strings and comments - #511
Open
JonasJesus42 wants to merge 1 commit into
Open
fix(migrate): ctx codemod no longer rewrites inside strings and comments#511JonasJesus42 wants to merge 1 commit into
JonasJesus42 wants to merge 1 commit into
Conversation
…comments
`transformCtxCompat` walks the file character by character with no notion of
string or comment boundaries, so a `ctx.` occurring as *text* was rewritten the
same as one occurring as code:
console.log('ctx.device:', ctx.device);
-> console.log('ctx?.device:', ctx?.device);
The call site is patched correctly and the message next to it is silently
corrupted — it still compiles, so nothing catches it. Same for double-quoted
strings, line and block comments, and template literal text.
Adds a literal/comment guard to the scan loop. Template literals are tracked
with a small context stack rather than skipped wholesale, because their `${}`
interpolations ARE code: `` `${ctx.vtex.account}` `` must still be rewritten
while `` `ctx.device` `` must not.
Regex literals are deliberately left untracked, and the reason is in a comment:
telling `/re/` from division requires real parsing, and guessing wrong would
consume live code. A `ctx.` inside a regex in a loader is vanishingly rare next
to that risk.
Five regression tests, four of which fail against the previous implementation
(verified by reverting the source and re-running).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
hugo-ccabral
approved these changes
Aug 28, 2026
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.
Context
The
transformCtxCompatcodemod (Fresh → TanStack migration) turnsctxreads into optional chains, so thatan app not configured on the target site yields
undefinedinstead of throwing — without it,withSectionLoaderswallows the exception and the section renders blank.It walks the file character by character, with no notion of string or comment boundaries. The result is
that a
ctx.appearing as text was rewritten just like one appearing as code:The call site is patched correctly and the message next to it is silently corrupted. And it compiles, so
nothing catches it — not the build, not typecheck, not tests. Same for double-quoted strings, line and block
comments, and template literal text.
No test covered this.
What changes
A literal/comment guard in the scan loop. On
//,/* */,'…'or"…", the span is copied verbatiminstead of scanned.
Template literals are not skipped wholesale, because their interpolations are real code. They are tracked
with a small context stack, so:
This also covers nested templates (
`a${`b${ctx.device}`}c`) and escaped quotes inside strings.Regex literals are deliberately left out, and the reason is in a code comment: telling
/re/from adivision requires real parsing, and guessing wrong would make the scanner consume live code. A
ctx.inside aregex in a loader is vanishingly rare next to that risk.
Why not
ts-morphblocks-clialready depends onts-morph, and rewriting via AST would eliminate the entire bug class ratherthan the cases we happened to think of. I didn't do it here because the scanner carries subtle, already-tested
logic (
isAssignTarget, already-optional chains, balanced computed access), and the rewrite would carryregression risk out of proportion to the bug. Noting it as a known path if the scanner needs to grow again.
Validation
Five regression tests. Four of them fail against the previous implementation — verified by reverting the
source and re-running, so the tests aren't decorative:
13tests in the file (8 existing + 5 new), all passing. Full suite at2589passing; the 4draft previewfailures are pre-existing on
main. Lint and typecheck clean.Provenance
Found by a
/code-reviewthat announced itself as being for #510. It isn't: #510 had 16 files and none ofthem was
ctx-compat.ts(checked via the GitHub API). The review most likely ran against another workspace'slocal diff. The bug is real and independent of any PR, hence this going separately.
🤖 Generated with Claude Code