main ← fix-hashtag-autocomplete-safe-mode-crash
opened 08:12PM - 14 Apr 26 UTC
When plugins are disabled via safe mode (e.g. ?safe_mode=no_plugins), Discourse …skips the plugins' JS assets but the plugins' Ruby code still runs. That means server endpoints like /hashtags/search.json and /hashtags can still return results with plugin-contributed types (e.g. the chat plugin's "channel" type), while the client-side class that knows how to render that type was never registered via api.registerHashtagType.
The autocomplete and hashtag decoration code then did:
getHashtagTypeClasses()[result.type].generateIconHTML(opts)
which throws "Cannot read properties of undefined (reading 'generateIconHTML')" and aborts the whole autocomplete promise, so the menu never shows any results.
Fix this at three levels:
1. In hashtag-autocomplete.js, filter the `order` sent to /hashtags/search.json down to the types the client can actually render. The client is authoritative about what it can display, so this avoids asking the server for results we'd have to throw away.
2. In hashtag-autocomplete.js and the prosemirror hashtag extension, guard the `generateIconHTML` call so an unregistered type renders without an icon instead of crashing. This protects against stale responses from /hashtags (the cooking lookup endpoint), plugin load races, and any future caller that bypasses the filter.
3. In hashtag-decorator.js, guard `generatePlaceholderHashtagHTML` which cooks hashtags in the markdown preview. The sibling decorateHashtags path already had a similar guard. While there, also drop a stray `new` keyword that was a no-op due to operator precedence (introduced in #25397).
Tests cover the three paths:
- Acceptance: only registered types are requested, and the autocomplete doesn't crash when the server returns an unregistered type.
- Integration: the prosemirror cooking path renders without an icon (and without crashing) for an unregistered type.
https://meta.discourse.org/t/400570