Troubleshooting
Common issues and solutions
Setup issues
bun install fails
Make sure you have Bun installed and you're on Node.js v22+:
bun --version # any recent 1.x
node --version # Should be v22 or higherDon't have Bun yet? Install it from bun.sh. Update Node.js via nvm or the official installer.
bun run dev fails or nothing loads
- Missing
.envfile: Make sure you copied.env.exampletopackages/infra/.envand filled in your Twitch keys andBETTER_AUTH_SECRET. See Getting started. - Slow first start: The first run creates the local database and compiles the apps. Give it a minute — later starts are much faster.
- Port already in use: Dirework uses port 3000 (API), 3001 (web app), and 4000 (docs). See Port already in use below.
Authentication issues
"Invalid redirect URI" from Twitch
Your Twitch application's redirect URLs don't match the ones Dirework is using. Make sure you've added both URLs in the Twitch Developer Console:
http://localhost:3001/api/auth/callback/twitch
http://localhost:3001/api/bot/callback/twitchFor production, add the same two paths on your workers.dev domain
(https://dirework.<your-subdomain>.workers.dev/...). See Twitch integration setup for details.
Can't sign in / redirects back to login
- Check that
BETTER_AUTH_URLmatches the URL you're accessing the app from exactly — protocol, host, and port (e.g.,http://localhost:3001locally,https://dirework.<your-subdomain>.workers.devin production). - Check that
CORS_ORIGINmatches as well. - Your Twitch redirect URLs must be on that same origin — a mismatch sends you in a loop.
- Make sure your Twitch application's Client Type is set to Confidential.
Bot account won't connect
- You need to sign in to a different Twitch account when connecting the bot. The bot account cannot be the same as the streamer account.
- Make sure the second redirect URL (
/api/bot/callback/twitch) is registered in your Twitch application.
Overlay issues
Overlay shows a blank page
- The timer overlay is blank on purpose while the timer is idle — start a timer session and it appears.
- Check that the overlay URL is correct. Copy it from the Overlay URLs card in the dashboard.
- Treat overlay URLs as bearer credentials. If one was exposed, regenerate its token and update OBS.
- Try opening the overlay URL directly in your browser to see if it loads.
Overlay not updating in OBS
- Overlays check for changes every few seconds — a short delay after adding a task or starting the timer is normal. The timer countdown itself ticks smoothly on the overlay, so it never looks laggy.
- Did you regenerate the overlay token? Regenerating kills the old URL — re-copy the fresh URL from the dashboard and paste it into your OBS browser source.
- OBS browser sources cache aggressively. Right-click the source and click Refresh cache of current page.
- Make sure "Shutdown source when not visible" is checked in the browser source settings so it reloads when you switch scenes.
Overlay has a white/colored background in OBS
The overlays are designed to be transparent. In OBS browser source settings, make sure Custom CSS is not overriding the background. The default CSS should be fine — just leave it empty or at the OBS default.
Timer issues
Timer stuck at 0:00 / not transitioning
The timer only moves forward while something is watching it — an open timer overlay in OBS (which checks in every few seconds), an open dashboard, or an incoming chat command. There is no always-on server, so something has to be watching for the timer to advance.
- Keep a timer overlay live in OBS (or the dashboard open) while the timer is running — either one nudges it forward
- If the timer is genuinely stuck, try clicking Stop (square button) and starting a new session
Timer starts but only counts down 5 seconds
This is the starting phase — a 5-second countdown before Focus begins. After the countdown reaches 0, the timer automatically moves into the Focus phase (25 minutes by default). If it doesn't, see the issue above.
Timer settings not saving
Timer duration settings (Focus, Break, Long break, interval, pomos) are saved when you click out of the input field. Make sure to:
- Change the value in the input
- Click somewhere else or tab out of the field
- The value is saved to the server automatically
Settings are only editable when the timer is idle or finished. They're disabled during an active session.
Timer doesn't use my configured duration
If you changed the work duration (e.g. to 50 minutes) but the timer still uses 25 minutes:
- Make sure you saved the setting (click out of the input field)
- Stop any running timer session with the stop button
- Start a new session — the timer reads durations from the database when starting
Chat bot issues
Bot not responding to commands
The bot only listens to chat while its bot page is open somewhere. Run through this list:
- Is exactly one bot page open? Copy the bot page URL from Dashboard → Bot and add it to OBS as a browser source (or keep it open in one pinned browser tab). If no copy is open, the bot hears nothing; if multiple copies are open, the same command can be processed twice.
- Was the bot token regenerated? Regenerating the token kills any previously copied bot page URL. Re-copy the fresh URL from Dashboard → Bot and update your OBS source or pinned tab. Treat this URL as a bearer credential and never post it publicly.
- Is a bot account connected? Check the Bot account card — connect a bot account if it isn't.
Commands work but messages aren't sent
- The bot account needs the
chat:readandchat:editscopes (the IRC connection the bot page uses requires them). If you connected the bot before these scopes were required, disconnect and reconnect it. - Check that the bot account isn't banned or timed out in your channel.
Development issues
TypeScript errors after pulling changes
Check types:
bun run check-typesChanges to Drizzle schema not reflected
After modifying the schema files in packages/db/src/schema/, generate a migration:
bun run db:generateMigrations are applied to the local database automatically the next time you run
bun run dev (and to production on deploy).
Port already in use
The API runs on port 3000, the web app on 3001, and the docs on 4000. If one of these ports is taken:
- Find what's using the port:
lsof -i :3001 - Kill that process, or change the port in the respective app's dev configuration.
Still stuck?
If your issue isn't covered here:
- Check the GitHub Issues for known bugs
- Open a new issue with details about your environment and the error you're seeing
- Join the Discord for community help