Claude Code: Mod lädt nicht oder rendert leer? Diese drei Ursachen kommen am häufigsten vor
Lädt ein Mod ohne Fehlermeldung einfach nicht, steckt die Ursache meist in einem von drei Problemen: Die statische Analyse hat das gesamte Mod verworfen, die Hook-Laufzeitumgebung fehlte, oder der zurückgegebene Tree verletzt die Component-Regeln. Ein Blick auf diese Punkte zeigt meist schnell, wo es hakt.

Wenn ein Mod nichts tut und keinen Fehler anzeigt, liegt die Ursache fast immer in einer von drei Gruppen: (1) Er hat die statische Analyse nicht bestanden und der gesamte Mod wurde nicht geladen, (2) er verwendet etwas, das die Hook-Runtime nicht besitzt, und der Hook wurde uebersprungen, oder (3) der zurueckgegebene Tree hat die Komponentenregeln verletzt, sodass Claude Code seine eigene UI gezeichnet hat. Beginnen Sie mit claude plugin validate und suchen Sie anschliessend im Debug-Log nach dem Namen des Mods.
Die offizielle Seite zur Fehlerbehebung beginnt mit folgendem Hinweis: Wenn ein Mod nicht laedt oder ein Hook fehlschlaegt, ueberspringt Claude Code ihn und fuehrt die Sitzung weiter. Ein defekter Mod sieht genau so aus wie ein Mod, der nichts tut.
Dieses Design verhindert, dass Claude Code selbst ausfaellt, hinterlaesst aber dem Autor nur wenige Anhaltspunkte. Man sollte sich daher im Voraus entscheiden, wo man sucht.
claude plugin validate. \my-mod Enter fullscreen mode Exit fullscreen mode Ohne eine Sitzung zu starten, fuehrt dieser Befehl dieselbe statische Analyse aus, die Claude Code beim Laden durchfuehrt. Er findet falsch geschriebene Events, fehlerhafte Manifeste und nicht lesbare Module.
Beim Laden wird der Quellcode des Moduls analysiert, und wenn dies fehlschlaegt, wird das gesamte Plugin nicht geladen.
Letzteres betrifft besonders die Desktop-App. Die Desktop-App bündelt ein eigenes Claude Code, das aelter sein kann als Ihre Terminal-Version. Ich hatte einen Mod, der ui.fault registrierte (das Event fuer Fehler in Client-Komponenten). Er funktionierte im Terminal, verschwand aber auf dem Desktop vollstaendig (gebundelte Version 2.1.286). Die offizielle Referenz gibt inzwischen an, dass ui.fault v2.1.289 oder neuer erfordert. Wenn Sie ein neues Event verwenden, vergleichen Sie den Versionshinweis in der Referenz mit der Version, die /status auf dem Desktop anzeigt.
Hooks laufen in einer Umgebung, die weder Node noch ein Browser ist. Die offizielle API-Seite sagt ebenfalls aus, dass es keine Node.js-APIs und keine Timer wie setTimeout gibt.
Im eigenen Code schreibt man diese Stellen einfach um. Die Schwierigkeit entsteht, wenn man ein npm-Paket hineinkopiert: Es liest process.env im Moment des Ladens, wirft einen Fehler, und der gesamte Mod verschwindet stillschweigend. Lokale Stellvertreter am Anfang der Datei dieses Pakets, auf diese Datei beschraenkt, haben das Problem geloest.
const process = { env: {} } const setTimeout = () => 0 Enter fullscreen mode Exit fullscreen mode Zeitlimits Das andere Thema ist Zeit. Dies sind die Limits aus der offiziellen Referenz, auf die Am haeufigsten stossen.
Hooks, die laenger als 10 Sekunden laufen, werden uebersprungen. Wenn Sie schwere Arbeit in einem Guard ausfuehren, der Tool-Aufrufe blockiert ( tool.check ), wird der Guard selbst umgangen, seien Sie also vorsichtig.
Wenn der aus ui.render zurueckgegebene Tree die Regeln verletzt, zeichnet Claude Code ohne Fehlermeldung seine eigene UI. Ihr Bereich verschwindet einfach und die Standardansicht kehrt zurueck, was dies zur am schwersten erkennbaren Problematik macht.
Bei bedingten Feldern schleicht sich undefined leicht ein, deshalb wickle ich die Komponenten-Factories an einer Stelle ein und entferne diese Werte.
// Keine Felder ohne Wert an Komponenten uebergeben function strip ( raw ) { const out = {} for ( const k of Object. keys ( raw )) { const make = raw [ k ] out [ k ] = typeof make === ' function '? ( props = {}) => make ( Object. fromEntries ( Object. entries ( props ). filter (([, v ]) => v!== undefined ))): make } return out } const t = strip ( $. ui. resolve ( e )) t. Button ({ key: ' pdf ', label: ' PDF ', plain: true, dimColor: busy? true: undefined, onPress }) Enter fullscreen mode Exit fullscreen mode Die Schreibweise dimColor: busy? true: undefined verhindert, dass jemals false uebergeben wird.
Wenn ein Modul nicht laedt, ein Hook uebersprungen wird oder ein Tree abgelehnt wird, schreibt Claude Code eine Zeile, die den Namen des Mods enthaelt. Wohin sie geht, haengt von der Sitzung ab (offizielle Seite zur Fehlerbehebung).
Anders gesagt: Wenn ein installierter Mod still ist, wird man durch langes Betrachten der Konversation nichts finden. Zeichnen Sie ein Debug-Log auf.
claude --debug-file. \mod-debug.log --plugin-dir. \my-mod Enter fullscreen mode Exit fullscreen mode Verfolgen Sie das Log in einem anderen Fenster (PowerShell-Beispiel).
Get-Content. \mod-debug.log -Wait | Select-String my-mod Enter fullscreen mode Exit fullscreen mode Dies sind die Zeichenketten, nach denen Sie suchen sollten:
Eine Zeile wie ui.render (Pane) refused: Text prop "bogusProp" is not allowed sagt Ihnen genau, welche Prop an welcher Komponente falsch ist. Probleme aus Gruppe 3, den Komponentenregeln, lassen sich fast immer mit einem Blick auf diese Zeile loesen.
Um eigene Markierungen zu schreiben, verwenden Sie $.ui.log('got here', { to: 'debug' })), um ins Log zu schreiben.
Die Desktop-App kann keine Start-Flags entgegennehmen, daher funktioniert der oben beschriebene Weg nicht direkt. Wie man aus der Desktop-App ein Debug-Log erfasst, wird auf den offiziellen Seiten nicht beschrieben und ist daher nicht verifiziert. Meine Routine ist es, denselben Mod im Terminal mit --debug-file zu laden, die Ursprungszeile zu finden, sie zu beheben und dann in der Desktop-App zu pruefen. Allerdings lassen sich Dinge, die nur auf dem Desktop fehlschlagen, wie ein fehlendes Event in dieser Version, im Terminal nicht reproduzieren, pruefen Sie daher zuerst mit /status die Desktop-Version.
Bevor Sie Ihrem Mod die Schuld geben: Mods koennen per Konfiguration deaktiviert sein. Fuehren Sie claude plugin test in einem Ordner ohne Mod aus, um den Zustand zu sehen.
Weitere Ursachen dafuer, dass ueberhaupt nichts geladen wird, sind ein nicht bestaetigter Trust-Prompt fuer einen neu geoeffneten Ordner sowie ein Start mit --safe-mode oder --bare.
Um zu sehen, wie andere Mods geschrieben sind, sodass sie die statische Analyse bestehen, lesen Sie sie in der code-reviewed-Liste der Mods. Jeder dort gelistete Mod ist Code, den claude plugin validate lesen kann.
Dieser Artikel wurde mit KI-Unterstuetzung (Claude) geschrieben und anhand der offiziellen Claude Code-Dokumentation geprueft; alles, was als "nicht verifiziert" markiert ist, konnte dort nicht bestaetigt werden.
Automatisch übersetzt. Das Original auf Englisch ist unten aufklappbar.
Original (Englisch) anzeigen
When a mod does nothing and shows no error, the cause almost always falls into one of three groups: (1) it failed static analysis and the whole mod was not loaded, (2) it used something the hook runtime does not have and the hook was skipped, or (3) the tree it returned broke the component rules, so Claude Code drew its own UI instead. Start with claude plugin validate, then search the debug log for the mod's name.
The official troubleshooting page opens with this: when a mod fails to load or a hook fails, Claude Code skips it and keeps the session going. A broken mod looks the same as a mod that does nothing.
That design keeps Claude Code itself from going down, but it leaves the author with few clues. So decide in advance where to look.
claude plugin validate. \my-mod Enter fullscreen mode Exit fullscreen mode Without starting a session, this runs the same static analysis Claude Code runs at load time. It catches misspelled events, broken manifests, and unreadable modules.
At load time, the module source is analyzed, and if it fails, the whole plugin is not loaded.
That last one hits the desktop app in particular. The desktop app bundles its own Claude Code, which can be older than your terminal version. I had a mod that registered ui.fault (the event for Client component failures). It worked in the terminal but vanished entirely on the desktop (bundled 2.1.286). The official reference now says ui.fault requires v2.1.289 or later. When you use a new event, compare the version note in the reference with the version shown by /status on the desktop.
Hooks run in an environment that is neither Node nor a browser. The official API page also says there are no Node.js APIs and no timers like setTimeout.
In your own code, you just rewrite these. The trouble comes when you copy in an npm package: it reads process.env the moment it loads, throws, and the whole mod silently disappears. Putting local stand-ins at the top of that package's file, scoped to that file only, got it through.
const process = { env: {} } const setTimeout = () => 0 Enter fullscreen mode Exit fullscreen mode Time limits The other issue is time. These are the limits from the official reference that people hit most often.
Hooks that run longer than 10 seconds are skipped. If you do heavy work in a guard that blocks tool calls ( tool.check ), the guard itself gets bypassed, so be careful.
If the tree returned from ui.render breaks the rules, Claude Code draws its own UI without any error. Your band just disappears and the default comes back, which makes this the hardest one to notice.
Conditional fields naturally let undefined slip in, so I wrap the component factories in one place and strip those values.
// Do not pass fields that have no value to components function strip ( raw ) { const out = {} for ( const k of Object. keys ( raw )) { const make = raw [ k ] out [ k ] = typeof make === ' function '? ( props = {}) => make ( Object. fromEntries ( Object. entries ( props ). filter (([, v ]) => v!== undefined ))): make } return out } const t = strip ( $. ui. resolve ( e )) t. Button ({ key: ' pdf ', label: ' PDF ', plain: true, dimColor: busy? true: undefined, onPress }) Enter fullscreen mode Exit fullscreen mode Writing dimColor: busy? true: undefined avoids ever passing false.
When a module fails to load, a hook is skipped, or a tree is rejected, Claude Code writes one line containing the mod's name. Where it goes depends on the session (official troubleshooting page).
In other words, when an installed mod is silent, no amount of looking at the conversation will show anything. Capture a debug log.
claude --debug-file. \mod-debug.log --plugin-dir. \my-mod Enter fullscreen mode Exit fullscreen mode Watch the log in another window (PowerShell example).
Get-Content. \mod-debug.log -Wait | Select-String my-mod Enter fullscreen mode Exit fullscreen mode These are the strings to look for:
A line like ui.render (Pane) refused: Text prop "bogusProp" is not allowed; the engine drew its own tells you exactly which prop on which component is wrong. Problems in group 3, component rules, are almost always solved in one look at this line.
To write your own markers, use $.ui.log('got here', { to: 'debug' }) to write to the log.
The desktop app cannot take launch flags, so the approach above does not work as is. How to capture a debug log from the desktop app is not described on the official pages, so it is not verified. My routine is to load the same mod in the terminal with --debug-file, find the reason line, fix it, and then check in the desktop app. However, things that fail only on the desktop, like an event missing from that version, do not reproduce in the terminal, so check the desktop version with /status first.
Before blaming your mod, mods may be turned off by configuration. Run claude plugin test in a folder with no mod to see the state.
Other causes of "nothing loads at all" include not having answered the trust prompt for a newly opened folder, and starting with --safe-mode or --bare.
To see how other mods are written so they pass static analysis, read them in the modscode reviewed list. Every mod listed there is code that claude plugin validate can read.
This article was written with AI assistance (Claude) and checked against the official Claude Code docs; anything marked "not verified" could not be confirmed there.