Skip to main content

Debugging

This guide covers common debugging techniques for Lumio extension development, from local dev server issues to production server function errors.

Local development

Dev server logs

When lumio dev is running, logs from server functions are printed directly to the terminal. Look for lines prefixed with [server]:

[server] INFO getScoreboard called with { sport: "basketball", league: "nba" }
[server] ERROR getScoreboard failed: ESPN API error: 429

Add console.log() statements in your handler freely during development — they appear in the terminal and are stripped from the production build.

Inspecting the overlay preview

The dev server opens a preview at http://localhost:3010/preview. This page renders the layer surface inside a 1920×1080 canvas. Open your browser's DevTools (F12) to:

  • Inspect the React component tree
  • Check the console for SDK errors
  • Profile render performance

The editor panel is at http://localhost:3010/editor and the interactive page at http://localhost:3010/interactive.

Simulating events

Use --mock to load a mock events file:

lumio dev --mock ./mocks/events.json

The events file is an array of event objects:

[
{
"type": "twitch:follower",
"timestamp": "2026-05-01T10:00:00Z",
"data": { "userName": "testuser", "userId": "u_001", "followedAt": "2026-05-01T10:00:00Z" }
},
{
"type": "spotify:track",
"timestamp": "2026-05-01T10:01:00Z",
"data": {
"title": "Test Track",
"artist": "Test Artist",
"album": "Test Album",
"albumArtUrl": "https://i.scdn.co/image/placeholder",
"duration": 210000,
"progress": 45000,
"isPlaying": true
}
}
]

In the preview UI, click Send Event to dispatch the next event from the file.


Debugging server functions

Checking logs in production

Stream production logs with:

lumio logs --tail

Filter by error level:

lumio logs --level error --since 1h

Common server function errors

"Host not in allowHosts"

You called ctx.fetch() with a host not listed in egress.allowHosts. Add the host to lumio.config.json:

{
"egress": {
"allowHosts": ["api.example.com"]
}
}

"Secret key not found: MY_KEY"

The secret hasn't been set for this extension. Run:

lumio secrets set MY_KEY "your_value_here"

"Action invocation timeout"

The handler took longer than 30 seconds. Check for:

  • Slow external API calls — add a timeout to ctx.fetch()
  • Unbounded loops in the handler
  • Large storage reads/writes
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), 8_000);
const res = await ctx.fetch("https://slow-api.example.com/data", {
signal: controller.signal,
});
clearTimeout(timeout);

"Storage key size exceeded"

The value you tried to store is larger than 64 KB. Compress or split the data across multiple keys.


React component debugging

Unexpected re-renders

If your layer re-renders too frequently, check:

  1. useLumioEvent in a dependency array — the event reference changes on every new event. If your useEffect depends on the event, it runs on every event. That is the intended behavior.

  2. Object/array literals in style props — create style objects outside the component or use useMemo:

// Bad — new object on every render
<Box style={{ color: "red", padding: 8 }}>

// Good — stable reference
const containerStyle: React.CSSProperties = { color: "red", padding: 8 };
<Box style={containerStyle}>
  1. setConfig in a loopsetConfig triggers a re-render and a network call. Batch updates:
// Bad
await setConfig({ a: 1 });
await setConfig({ b: 2 });

// Good
await setConfig({ a: 1, b: 2 });

White screen / nothing renders

  1. Check the browser console for JavaScript errors
  2. Make sure Lumio.render() is called at the module level, not inside a React component
  3. Verify the target in Lumio.render() matches the URL you're previewing (layer, editor, or interactive)

Build errors

TypeScript errors

Run the TypeScript compiler to see all type errors at once:

cd my-extension && npx tsc --noEmit

Bundle too large

Run lumio build --analyze to see which modules contribute to the bundle size. Common culprits:

  • Importing entire icon libraries — import individual icons instead
  • Importing large utility libraries — check if a smaller alternative exists
  • Embedding image data as base64 — use external URLs or the static assets folder instead

MDX / JSX syntax error in docs

Not applicable to extensions, but if you're editing apps/developer-docs/docs/, remember that {placeholder} in MDX headings must be escaped as \{placeholder\} outside code fences.