Skip to content

Packaged desktop app can crash in main process with write EPIPE from electron-log console transport #25927

Description

@jamestotah

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:

  1. The packaged main process still initializes logging without disabling console transport:
function initLogging() {
  log.transports.file.maxSize = 5 * 1024 * 1024;
  cleanup();
  return log;
}
  1. 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.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions