B · Launching Effectstream + Local Dev · APPENDIX
Troubleshooting
Symptom → cause → fix. First move is always the same: bunx orchestrator status.
▼ details below
| Symptom | Cause | Fix |
|---|---|---|
| Everything runs, no errors, but nothing ever appears in the API | NTP (UDP 123) blocked — the main timeline can't sync time, so no blocks are processed. Common on corporate VPNs/hotel Wi-Fi. | Test with sntp time.google.com (mac) / ntpdate -q pool.ntp.org (linux). Switch networks or disable the VPN. |
| Mints sync but everything stalls after some point; or nothing syncs and a Midnight process is red | A Midnight process (node/indexer/proof server) died — parallel chains gate the whole pipeline. | bunx orchestrator status, then bunx orchestrator logs midnight-node (or indexer). Usually fixed by stop + start again. |
Cannot find module '@evm-midnight/…' at startup (rare) |
On some bun/OS combinations the workspace symlinks under node_modules/@evm-midnight/ aren't created by bun install. |
Check ls node_modules/@evm-midnight/. If empty, run the symlink script below once from the template root. |
Foundry's forge was not found / compact was not found |
Startup hard-checks both toolchains. | Install per Setup; restart your shell so PATH updates. |
| Frontend build dies with heap out of memory / SIGKILL | vite needs ~3 GB heap (the bundle includes the Midnight wallet SDK). | Free RAM; if using Docker/VM give it ≥ 6 GB. |
address already in use on 8545/9944/10599… |
A previous run is still holding ports — or another app owns one (a local PostgreSQL on 5432 is the classic). Full list on First launch. | bunx orchestrator stop. Local Postgres: stop the service. Still stuck: lsof -ti tcp:8545 | xargs kill. |
| First launch hangs downloading | Midnight binaries come from GitHub releases on first run. | Wait it out on good Wi-Fi; it's a one-time download. |
| MetaMask: tx stuck pending / nonce error after a restart | The chain was reset but MetaMask remembers old nonces. | MetaMask → Settings → Advanced → Clear activity tab data (per account). |
| MetaMask mint rejected / wrong chain | Not on the local Hardhat network. | Use the game's Connect wallet button — it adds/switches to chain 31337. |
Placements accepted by batcher (success:true) but never reach the map |
Either the Game_L2 primitive isn't in config.dev.ts yet (Step 4), or the batcher/node namespaces don't match. |
Finish Step 4; check namespace in batcher.dev.ts equals "evm-midnight-node", then restart batcher + sync. |
bun run build:pgtypes fails with Failed to listen |
pgtyped starts its own PGLite on port 5432 — it conflicts with the running stack's database. | Run it while the stack is stopped (bunx orchestrator stop), then start again. |
| Cards/map render but battle math seems off | You tuned constants in game.ts and only restarted one piece. |
bunx orchestrator restart sync — the STM lives in the sync process. |
Missing workspace links (rare)
If ls node_modules/@evm-midnight/ comes back empty after bun install,
create the workspace symlinks manually (this is the same workaround the template's Dockerfile
uses). Run once from the template root — and again after any later bun install:
bun -e "
const fs = require('fs'); const path = require('path');
const pkg = JSON.parse(fs.readFileSync('package.json','utf8'));
for (const pattern of pkg.workspaces || []) {
for (const dir of new Bun.Glob(pattern).scanSync({onlyFiles:false})) {
const p = path.join(dir,'package.json');
if (!fs.existsSync(p)) continue;
const wp = JSON.parse(fs.readFileSync(p,'utf8'));
if (!wp.name) continue;
const [scope,name] = wp.name.startsWith('@') ? wp.name.split('/') : [null,wp.name];
const linkDir = scope ? path.join('node_modules',scope) : 'node_modules';
fs.mkdirSync(linkDir,{recursive:true});
const link = path.join(linkDir,name);
if (!fs.existsSync(link)) fs.symlinkSync(path.resolve(dir), link);
}
}"
Nuke it from orbit
bunx orchestrator stop
bun run dev
The database is in-memory: a restart replays state from the chains — which, conveniently,
is also a live demonstration of why determinism matters.