Summary
On macOS, the packaged OpenCode desktop app can crash in the Electron main process with:
A JavaScript error occurred in the main process
Uncaught Exception:
Error: write EPIPE
at afterWriteDispatched (node:internal/stream_base_commons:159:15)
at writeGeneric (node:internal/stream_base_commons:150:3)
at Socket._writeGeneric (node:net:966:11)
at Socket._write (node:net:978:8)
at writeOrBuffer (node:internal/streams/writable:570:12)
at _write (node:internal/streams/writable:499:10)
at Writable.write (node:internal/streams/writable:508:10)
at console.value (node:internal/console/constructor:313:16)
at console.info (node:internal/console/constructor:423:26)
at transport.writeFn (/Applications/OpenCode.app/Contents/Resources/app.asar/node_modules/electron-log/src/node/transports/console.js:60:7)
This looks like the packaged GUI app is still using electron-log's console transport, and a normal log write can crash the main process if stdout/stderr has already gone away.
Environment
- macOS 26.4 (Apple Silicon)
- OpenCode desktop
1.14.39
- Installed app bundle path:
/Applications/OpenCode.app
Why I think this is a real desktop bug
I unpacked the installed app.asar and confirmed:
- The packaged main process still initializes logging without disabling console transport:
function initLogging() {
log.transports.file.maxSize = 5 * 1024 * 1024;
cleanup();
return log;
}
- The bundled
electron-log console transport writes directly to console.info / console.log:
writeFn({ message }) {
const consoleLogFn = consoleMethods[message.level] || consoleMethods.info;
consoleLogFn(...message.data);
},
So if the packaged Electron process is launched in a state where stdout/stderr is not writable, a normal log write can surface as write EPIPE in the main process.
Repro notes
I do not yet have a 100% minimal reproduction from a clean machine, but I hit this immediately after a launch/integration failure involving OpenChamber managing OpenCode.
What makes me think this still belongs here:
- the stack is entirely inside OpenCode desktop main-process logging
- the installed packaged app currently ships the risky code path above
- a packaged GUI app should not crash because a console transport wrote to a dead pipe
Expected behavior
If stdout/stderr is gone, packaged desktop builds should continue running and keep file logging only.
Actual behavior
Main process throws uncaught Error: write EPIPE from the bundled electron-log console transport and shows the Electron crash dialog.
Suggested fix
Either of these would likely address it:
- disable
log.transports.console for packaged desktop builds
- or guard console transport writes against
EPIPE / broken pipe conditions
I locally patched the desktop source to do the first option and it typechecked cleanly:
if (app.isPackaged) {
log.transports.console.level = false
}
If helpful, I can provide the exact local source diff and more timing/context from the triggering launch sequence.
Summary
On macOS, the packaged OpenCode desktop app can crash in the Electron main process with:
This looks like the packaged GUI app is still using
electron-log's console transport, and a normal log write can crash the main process if stdout/stderr has already gone away.Environment
1.14.39/Applications/OpenCode.appWhy I think this is a real desktop bug
I unpacked the installed
app.asarand confirmed:electron-logconsole transport writes directly toconsole.info/console.log:So if the packaged Electron process is launched in a state where stdout/stderr is not writable, a normal log write can surface as
write EPIPEin the main process.Repro notes
I do not yet have a 100% minimal reproduction from a clean machine, but I hit this immediately after a launch/integration failure involving OpenChamber managing OpenCode.
What makes me think this still belongs here:
Expected behavior
If stdout/stderr is gone, packaged desktop builds should continue running and keep file logging only.
Actual behavior
Main process throws uncaught
Error: write EPIPEfrom the bundledelectron-logconsole transport and shows the Electron crash dialog.Suggested fix
Either of these would likely address it:
log.transports.consolefor packaged desktop buildsEPIPE/ broken pipe conditionsI locally patched the desktop source to do the first option and it typechecked cleanly:
If helpful, I can provide the exact local source diff and more timing/context from the triggering launch sequence.