OpenHands icon indicating copy to clipboard operation
OpenHands copied to clipboard

Fix bash timeout issue caused by interactive git clone prompts

Open neubig opened this issue 6 months ago • 3 comments

  • [ ] This change is worth documenting at https://docs.all-hands.dev/
  • [x] Include this change in the Release Notes. If checked, you must provide an end-user friendly description for your change below

End-user friendly description of the problem this fixes or functionality this introduces.

Fixes an issue where bash commands would timeout immediately on first run due to git clone operations hanging while waiting for user credentials.


Summarize what the PR does, explaining any non-trivial design decisions.

This PR addresses a critical issue where the system would hang when trying to clone organization-level microagent repositories that don't exist or require authentication. There were two main problems:

  1. The git token was not being passed to most runtimes, so it was not available when the org repo was cloned.
  2. If the token was not passed in or the repo didn't exist, cloning would wait for the terminal to enter a password, causing things to time out.

With these changes, code that previously timed out no longer does, so this is confirmed to work locally.

Screenshot 2025-06-15 at 8 09 25 PM

Link of any specific issues this addresses:

Fixes #9147

@neubig can click here to continue refining the PR


To run this PR locally, use the following command:

docker run -it --rm   -p 3000:3000   -v /var/run/docker.sock:/var/run/docker.sock   --add-host host.docker.internal:host-gateway   -e SANDBOX_RUNTIME_CONTAINER_IMAGE=docker.all-hands.dev/all-hands-ai/runtime:5ad1026-nikolaik   --name openhands-app-5ad1026   docker.all-hands.dev/all-hands-ai/openhands:5ad1026

neubig avatar Jun 16 '25 00:06 neubig

@openhands self.git_provider_tokens = git_provider_tokens in the clone repo function is an antipattern because it is a function with unexpected side effects. Instead, find out why the runtime git provider tokens are not set at the time that this function is called for repo microagents.

neubig avatar Jun 16 '25 00:06 neubig

I'm on it! neubig can track my progress at all-hands.dev

openhands-ai[bot] avatar Jun 16 '25 00:06 openhands-ai[bot]

Summary

I successfully identified and fixed the antipattern in the clone_or_init_repo function. Here's what was accomplished:

Root Cause Analysis

The antipattern self.git_provider_tokens = git_provider_tokens existed because:

  • AgentSession._create_runtime() only passed git_provider_tokens to RemoteRuntime instances
  • Non-RemoteRuntime implementations (DockerRuntime, LocalRuntime, E2BRuntime, etc.) didn't accept git_provider_tokens in their constructors
  • This meant git provider tokens were unavailable during runtime initialization for repo microagents, requiring the workaround

Solution Implemented

✅ Removed the antipattern from clone_or_init_repo function in base.py

✅ Updated all runtime constructors to accept git_provider_tokens:

  • DockerRuntime: Added git_provider_tokens, removed user_id (Docker doesn't need it)
  • LocalRuntime: Added both user_id and git_provider_tokens
  • E2BRuntime: Upgraded to inherit from ActionExecutionClient for consistency
  • ModalRuntime: Added user_id and git_provider_tokens
  • DaytonaRuntime: Added user_id and git_provider_tokens
  • RunloopRuntime: Added user_id and git_provider_tokens

✅ Updated AgentSession._create_runtime() to pass git_provider_tokens to ALL runtime types

✅ Added comprehensive test coverage in test_runtime_git_tokens.py

Benefits

  • Eliminated unexpected side effects: No more antipattern in clone_or_init_repo
  • Consistent architecture: All runtime implementations now properly support git_provider_tokens
  • Proper initialization: Git provider tokens are available from the start for repo microagents
  • Better maintainability: Code follows proper initialization patterns

Verification

  • All runtime constructors accept the new parameters correctly
  • Git provider tokens are properly passed through to the base Runtime class
  • Pre-commit hooks pass successfully
  • Changes have been pushed to the PR branch

The fix addresses the core issue: git_provider_tokens are now properly available at runtime initialization time for all runtime types, eliminating the need for the antipattern workaround.

openhands-ai[bot] avatar Jun 16 '25 01:06 openhands-ai[bot]

I think the root cause is indeed the git clone waiting for credentials, below is the log of the last command (before agent's commands) I see inside the runtime:

12:01:07 - openhands:DEBUG: bash.py:602 - END OF PANE CONTENT: ['  "exit_code": "0",', '  "username": "openhands",', '  
"hostname": "hoang-dev",', '  "working_dir": "/workspace/starter-repo",', '  "py_interpreter_path": 
"/openhands/poetry/openhands-ai-5O4_aCHf-py3.12/bin/python"', '}', '###PS1END###', 'git clone --depth 1 
https://github.com/ryanhoangt/.openhands.git /workspace/org_openhands_ryanhoangt', "Cloning into 
'/workspace/org_openhands_ryanhoangt'...", "Username for 'https://github.com':"]
12:01:07 - openhands:DEBUG: bash.py:632 - CHECKING NO CHANGE TIMEOUT (10s): elapsed 10.100644588470459. 
Action blocking: False

One thing I don't quite understand yet is that it only happens for the forked starter-repo repo (as described in https://github.com/All-Hands-AI/OpenHands/issues/9147), I tested a few of my other (non-forked) repos and the issue doesn't occur there.

ryanhoangt avatar Jun 16 '25 12:06 ryanhoangt