Skip to content

fix(muya): crash typing '#' β€” guard I18n.t + add heading-copy-link locale key - #4424

Merged
Jocs merged 3 commits into
developfrom
fix/muya-i18n-heading-copy-link-crash
Jun 9, 2026
Merged

Jocs merged 3 commits into
developfrom
fix/muya-i18n-heading-copy-link-crash

Conversation

@Jocs

@Jocs Jocs commented Jun 9, 2026

Copy link
Copy Markdown
Member

Crash

Typing # to create a heading throws in the renderer:

TypeError: Cannot read properties of undefined (reading 'Copy anchor link to this heading')
  at I18n.t (muya/src/i18n/index.ts)
  at new HeadingCopyLink (muya/src/block/commonMark/headingCopyLink/index.ts)

Root cause (two bugs)

  1. I18n.t is not crash-safe. return resources?.[lang]?.[key] || resources.en[key] || key β€” resources.en is undefined whenever the loaded locale isn't named en (the constructor stores only { [name]: resource }). A key missing from the current locale fell through to resources.en[key] β†’ throw.
  2. The key was never added to the locales. HeadingCopyLink (PG11, feat(muya): emit preview-image + heading-copy-link events (PG10/PG11)Β #4414) calls i18n.t('Copy anchor link to this heading'), but that key isn't in any locale resource β€” so it always hit the unguarded fallback.

Fix

  • resources.en[key] β†’ resources.en?.[key] (any missing key is now safe, every locale).
  • Added 'Copy anchor link to this heading' to all 9 locales (en/zh-CN/zh-TW/de/es/fr/ja/ko/pt).

Verified: lint, lint:types, full test green. This is a real-app regression the headless tests missed (the spec/e2e ran under the en default where resources.en exists) β€” exactly the Phase G class.

Jocs and others added 2 commits June 9, 2026 11:13
t() fell through to `resources.en[key]`, but `resources.en` is undefined
whenever the loaded locale is not named `en` (the constructor stores only
`{ [name]: resource }`). A key missing from the current locale therefore
threw `Cannot read properties of undefined` instead of falling back. Use
optional chaining so a missing key is always safe.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
The HeadingCopyLink affordance (PG11, #4414) used this i18n key but it was
never added to the locale resources, so typing `#` to create a heading
crashed in a non-en locale (and showed the raw key in en).

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Copilot AI review requested due to automatic review settings June 9, 2026 03:13

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a renderer crash triggered when creating a heading (#) by making I18n.t() resilient to missing locale entries and by adding the missing heading-copy-link label key across all Muya locales.

Changes:

  • Guarded the English fallback lookup in I18n.t() to avoid throwing when resources.en is missing.
  • Added the new locale key 'Copy anchor link to this heading' to all shipped locales (en/zh-CN/zh-TW/de/es/fr/ja/ko/pt).

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/muya/src/i18n/index.ts Makes translation fallback safer to prevent crashes when a key/locale is missing.
packages/muya/src/locales/en.ts Adds the heading copy-link label key.
packages/muya/src/locales/de.ts Adds the heading copy-link label key.
packages/muya/src/locales/es.ts Adds the heading copy-link label key.
packages/muya/src/locales/fr.ts Adds the heading copy-link label key.
packages/muya/src/locales/ja.ts Adds the heading copy-link label key.
packages/muya/src/locales/ko.ts Adds the heading copy-link label key.
packages/muya/src/locales/pt.ts Adds the heading copy-link label key.
packages/muya/src/locales/zh-CN.ts Adds the heading copy-link label key.
packages/muya/src/locales/zh-TW.ts Adds the heading copy-link label key.

πŸ’‘ Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 18 to 22
t(key: string): string {
const { lang, resources } = this;

return resources?.[lang]?.[key] || resources.en[key] || key;
return resources?.[lang]?.[key] || resources.en?.[key] || key;
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done β€” changed the en fallback to resources?.en?.[key] so both lookups optional-chain resources consistently and t() stays crash-safe even if resources is ever unset. Thanks!

Keeps I18n.t fully crash-safe and consistent with the primary lookup if
`resources` is ever unset.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
@Jocs
Jocs merged commit 8b36f7f into develop Jun 9, 2026
9 checks passed
Jocs added a commit that referenced this pull request Jun 9, 2026
…i18n keys (#4427)

An i18n-key audit (prompted by the #4424 heading-copy-link crash) found two
more keys used via i18n.t() but absent from the locale resources. Before
#4424's crash-safety fix these threw in a non-en locale; after it they
displayed the raw English key. Added both to all 9 locales.

Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
Jocs added a commit that referenced this pull request Jun 10, 2026
…4434)

Fill the highest-value missing automated tests from the @muyajs/core
migration regression audit β€” the recently-fixed bugs and data-loss-adjacent
paths that had no engine coverage.

- headingLocaleCrash.spec.ts (#4424/#4427 TOP priority): boots Muya under a
  non-en (zh-CN) locale and types `#` to create a heading, exercising the
  HeadingCopyLink `i18n.t` path that used to crash. Asserts no throw, the
  translated copy-anchor label resolves per-locale, the affordance still emits
  `heading-copy-link`, and `I18n.t` stays crash-safe (raw-key fall-through)
  for a key missing from a non-en locale.
- formatToggle.spec.ts: the public `Format.format()` toggle-OFF and `clear`
  paths over a real boot (strong/em/del/u/mark/link/inline-code) β€” only the
  apply-side `_addFormat` was previously covered.
- backspaceUnwrap.spec.ts (data-loss): Backspace-at-offset-0 cross-block
  surgery β€” paragraph merge + caret join point, and block-quote / list unwrap
  across all four branches (only/first/middle), asserting no item is dropped.
- tableCell backspaceSafety.spec.ts (data-loss): empty-table Backspace β†’
  paragraph replacement, and previous-cell caret jump without destructive merge.
- table insertRowColumn.spec.ts: insertRow/insertColumn shape, per-column
  alignment inheritance, delimiter round-trip, and returned caret cell β€” only
  the removal paths were previously unit-tested.

All assert already-correct behavior (coverage gaps, not failing-first) and pass
on current develop. Gates: lint, lint:types, check-circular, test, test:spec.

Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
@Jocs
Jocs deleted the fix/muya-i18n-heading-copy-link-crash branch June 10, 2026 07:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants