[BUG] Mods: a local variable named `h` breaks every JSX element in its scope, and `claude plugin validate` passes it
What's Wrong?
JSX in a hooks module compiles against the global h. If the module has a local variable named h (an arrow-function parameter is enough), every JSX element inside that scope calls the local value instead, and the hook throws h is not a function.
claude plugin validate passes the module. It already refuses a shadowed on and $ ("on is declared again (shadowed)"), but not a shadowed h.
In the desktop Code tab the pane then shows only "Nothing to show yet — <plugin> has not drawn in this pane", with no reason. I hit this with HELP.map(h => <Text key={h}>{h}</Text>) and spent a while looking at everything else.
What Should Happen?
claude plugin validate refuses a local h (and Fragment) the same way it refuses on and $, naming the line.
Steps to Reproduce
hooks/register.tsx:
import type { Register } from 'claude-code'
const LINES = ['one', 'two']
export const register: Register = on => {
on('ui.render', { component: 'Pane', requestId: 'h-shadow' }, async ($, e) => {
const { Box, Text } = $.ui.resolve(e)
return (
<Box flexDirection="column">
{LINES.map(h => <Text key={h}>{h}</Text>)}
</Box>
)
})
}
claude plugin validate .→✔ Validation passed with warningsclaude plugin test .with a test that mounts the pane ondesktop:
````
(fail) the pane draws
h-shadow's ui.render hook was skipped: h-shadow: h is not a function. (In 'h(Text, {
- Rename the parameter to
lineand change nothing else → the same test passes.
Environment
- Claude Code 2.1.296, Windows 11
- Desktop Code tab (seen there with 2.1.293)
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗