docmirror/dev-sidecar · warning

server process beforeExit, code:

Error message

server process beforeExit, code:

What it means

A warning log from the `beforeExit` handler attached to the forked mitmproxy child process (packages/core/src/modules/server/index.js:115-117). Node emits `beforeExit` on a child when its event loop drains and it is about to exit normally. In practice for this forked server it signals the child finished its work/loop and is shutting down on its own, code 0 usually meaning normal exit.

Source

Thrown at packages/core/src/modules/server/index.js:116

        serverConfig.app.instance = existingInstance
      }
      fs.writeFileSync(runningConfigPath, jsonApi.stringify(serverConfig))
      log.info('保存 running.json 运行时配置文件成功:', runningConfigPath)
    } catch (e) {
      log.error('保存 running.json 运行时配置文件失败:', runningConfigPath, ', error:', e)
      throw e
    }
    const serverProcess = fork(mitmproxyPath, [runningConfigPath])
    server = {
      id: serverProcess.pid,
      process: serverProcess,
      port: serverConfig.port,
      close () {
        serverProcess.send({ type: 'action', event: { key: 'close' } })
      },
    }
    serverProcess.on('beforeExit', (code) => {
      log.warn('server process beforeExit, code:', code)
    })
    serverProcess.on('SIGPIPE', (code, signal) => {
      log.warn(`server process SIGPIPE, code: ${code}, signal:`, signal)
    })
    serverProcess.on('exit', (code, signal) => {
      log.warn(`server process exit, code: ${code}, signal:`, signal)
    })
    serverProcess.on('uncaughtException', (err, origin) => {
      log.error('server process uncaughtException:', err)
    })
    serverProcess.on('message', (msg) => {
      log.debug('收到子进程消息:', JSON.stringify(msg))
      if (msg.type === 'status') {
        fireStatus(msg.event)
      } else if (msg.type === 'error') {
        let code = ''
        if (msg.event.code) {
          code = msg.event.code

View on GitHub (pinned to 7710cd56cc)

Solutions

  1. If you intentionally stopped the server, this is expected — ignore it.
  2. If the server died unexpectedly, check `~/.dev-sidecar/logs/server.log` and core.log for the real cause (port conflict, config parse error, uncaughtException above it).
  3. If the child exits on its own when idle, look for child-side code closing the HTTP/HTTPS listeners; restart via DevSidecar.api.restart() to recover.
  4. Verify running.json config is valid; invalid config can make the child exit right after boot.

Example fix

// before
serverProcess.on('beforeExit', (code) => {
  log.warn('server process beforeExit, code:', code)
})
// after
serverProcess.on('beforeExit', (code) => {
  log.warn('server process beforeExit, code:', code)
  if (code === 0 && autoRestartEnabled) {
    log.info('child exited normally but unexpectedly; restarting server')
    serverApi.restart({ mitmproxyPath })
  }
})
Defensive patterns

Strategy: validation

Validate before calling

const server = DevSidecar.api.server.getServer()
const alive = server && server.process && !server.process.killed && server.process.exitCode == null
if (alive) {
  console.log('server already running on port', server.port, '- skip startup')
} else {
  await DevSidecar.api.startup()
}

Type guard

function isServerAlive (server) {
  return Boolean(server && server.process && server.process.killed === false && server.process.exitCode == null)
}

Prevention

When it happens

Trigger: The mitmproxy child process's event loop empties (no active handles) so Node begins a normal exit; the child's close action completes; child code calls process.exit after loop drain.

Common situations: Server stopped via close() and the child drained cleanly; a bug in the child removes all keep-alive handles (e.g. server closed unexpectedly), making the proxy silently stop while the parent only logs a warning.

Related errors


AI-assisted analysis of docmirror/dev-sidecar@7710cd56cc (2026-08-31). Data as JSON: /api/errors/22d7fc6f1c85891e. Report an issue: GitHub.