Skip to content

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

@jamestotah

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
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions