Skip to content

Fix: mycoder CLI hanging issue - unresolved promises and processes #202

@github-actions

Description

@github-actions

Potential Causes for mycoder CLI Hanging Issue

Issue Summary

The mycoder CLI sometimes hangs and doesn't return to the shell even after showing a performance summary. This suggests there are unresolved promises or lingering processes preventing the Node.js process from exiting.

Identified Potential Causes

1. Unclosed Browser Sessions

The BrowserManager class in packages/agent/src/tools/browser/BrowserManager.ts sets up event listeners on process exit, but these may not be reliably triggered:

// Handle process exit
process.on('exit', () => {
  this.closeSession(session.id).catch(() => {});
});
  • The process.on('exit') handler can only run synchronous code - any async operations like closeSession() won't actually complete
  • If a browser session is left open, Playwright/Chromium processes may continue running

2. Unresolved Shell Processes

The shellStart tool in packages/agent/src/tools/system/shellStart.ts creates child processes that may not be properly terminated:

  • The global processStates map stores references to spawned processes
  • There's no cleanup mechanism to ensure all processes are terminated before the CLI exits
  • Long-running commands that switch to async mode might be left running

3. Missing Global Cleanup

The main CLI entry point in packages/cli/src/index.ts doesn't include a comprehensive cleanup routine:

await main()
  .catch(async (error) => {
    console.error(error);
    // Capture the error with Sentry
    captureException(error);
    process.exit(1);
  })
  .finally(async () => {
    // Report timings if profiling is enabled
    await reportTimings();
  });
  • The finally block only reports timings but doesn't ensure all resources are released
  • No explicit termination of browser sessions or shell processes

4. Event Listeners Preventing Exit

Node.js won't exit if there are active event listeners. Several components register event listeners:

  • BrowserManager adds process event handlers
  • shellStart adds listeners to process stdout/stderr
  • Any unhandled listeners can keep the Node.js event loop active

Recommended Fixes

  1. Implement a Comprehensive Cleanup Function:

    • Create a central cleanup function that closes all browser sessions, terminates all shell processes, and removes event listeners
    • Call this function in the finally block of the main CLI function
    • Use process.exit() after cleanup to ensure termination
  2. Fix Browser Session Cleanup:

    • Modify BrowserManager to use beforeExit event instead of exit for async cleanup
    • Implement a synchronous cleanup method for the exit event
    • Add a public closeAllSessions method that can be called during CLI shutdown
  3. Improve Shell Process Management:

    • Add a registry of all running processes
    • Implement a cleanup function that terminates all processes
    • Use proper signal handling to ensure child processes are terminated
  4. Add Debug Logging for Exit Process:

    • Add detailed logging during the shutdown process to identify hanging components
    • Log active handles and requests using process._getActiveHandles() and process._getActiveRequests()
  5. Force Exit After Timeout:

    • As a failsafe, implement a forced exit after a timeout period
    • Add a configurable timeout (e.g., 5 seconds) after which process.exit() is called

Implementation Priority

  1. Add comprehensive cleanup function to the main CLI
  2. Fix browser session cleanup
  3. Improve shell process management
  4. Add debug logging for exit process
  5. Implement force exit after timeout

Metadata

Metadata

Assignees

No one assigned

    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