Skip to content

OpenCode Github Agent Stuck! #4672

Closed as not planned
Closed as not planned

Description

@thehaseebahmed

Description

I've been trying for a bit but OpenCode GitHub Agent keeps on getting stuck at "Sending Message to opencode...".

OpenCode version

1.0.106

Steps to reproduce

No response

Screenshot and/or share link

Image

Operating System

ubuntu-latest

Terminal

Github Actions

Activity

  1. added
    opentuiThis relates to changes in v1.0, now that opencode uses opentui
    on Nov 24, 2025
  2. github-actions commented on Nov 24, 2025

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

    Feel free to ignore if your specific case differs from these issues.

  3. rekram1-node commented on Nov 24, 2025

    @rekram1-node
    Collaborator

    /oc test

  4. self-assigned this
    on Nov 24, 2025
  5. removed
    opentuiThis relates to changes in v1.0, now that opencode uses opentui
    on Nov 24, 2025
  6. opencode-agent commented on Nov 24, 2025

    @opencode-agent
    Contributor

    Investigation complete. The OpenCode GitHub Agent gets stuck due to session management issues in the ACP implementation, particularly around timeout handling and event processing loops.

    New%20session%20-%202025-11-24T00%3A56%3A57.417Z
    opencode session  |  github run

  7. rekram1-node commented on Nov 24, 2025

    @rekram1-node
    Collaborator

    thats made up ^ lol but ill look into it, ofc cant replicate tho

  8. rekram1-node commented on Nov 24, 2025

    @rekram1-node
    Collaborator

    What provider are u using?

  9. thehaseebahmed commented on Nov 24, 2025

    @thehaseebahmed
    Author

    What provider are u using?

    I'm using Claude Code Subscription. I can try with OpenCode Zen as well if that helps.

  10. rekram1-node commented on Nov 24, 2025

    @rekram1-node
    Collaborator

    If you are using claude code subscription how are you completing the oauth exchange in CI?

  11. thehaseebahmed commented on Nov 24, 2025

    @thehaseebahmed
    Author

    If you are using claude code subscription how are you completing the oauth exchange in CI?

    I had claude write me an OAuth Refresh job that checks for OAuth token expiry and refresh tokens when needed. It refreshes token fine and was working before, just became a more prominent issue since yesterday.

          - name: Refresh OAuth tokens if needed
            env:
              GH_TOKEN: ${{ secrets.GH_PAT }}
            run: |
              CURRENT_TIME=$(($(date +%s) * 1000))
              TOKEN_EXPIRES=${{ secrets.ANTHROPIC_EXPIRES }}
              
              # Check if token needs refresh (expires in less than 1 hour)
              if [ $((TOKEN_EXPIRES - CURRENT_TIME)) -lt 3600000 ]; then
                echo "🔄 Token expiring soon, refreshing..."
                
                RESPONSE=$(curl -s -w "\n%{http_code}" -X POST https://console.anthropic.com/v1/oauth/token \
                  -H "Content-Type: application/json" \
                  -d "{
                    \"grant_type\": \"refresh_token\",
                    \"refresh_token\": \"${{ secrets.ANTHROPIC_REFRESH_TOKEN }}\",
                    \"client_id\": \"9d1c250a-e61b-44d9-88ed-5944d1962f5e\"
                  }")
                
                HTTP_CODE=$(echo "$RESPONSE" | tail -1)
                BODY=$(echo "$RESPONSE" | head -n -1)
                
                if [ "$HTTP_CODE" -eq "200" ]; then
                  echo "✅ Token refresh successful!"
                  
                  NEW_ACCESS=$(echo "$BODY" | jq -r '.access_token')
                  NEW_REFRESH=$(echo "$BODY" | jq -r '.refresh_token')
                  EXPIRES_IN=$(echo "$BODY" | jq -r '.expires_in')
                  NEW_EXPIRES=$(($(date +%s) * 1000 + EXPIRES_IN * 1000))
                  
                  # Update GitHub Secrets for future runs
                  echo "📝 Updating GitHub secrets..."
                  gh secret set ANTHROPIC_ACCESS_TOKEN --body "$NEW_ACCESS"
                  gh secret set ANTHROPIC_REFRESH_TOKEN --body "$NEW_REFRESH"
                  gh secret set ANTHROPIC_EXPIRES --body "$NEW_EXPIRES"
                  
                  echo "✅ Tokens refreshed and persisted"
                else
                  echo "❌ Token refresh failed with status $HTTP_CODE"
                  echo "$BODY"
                  exit 1
                fi
              else
                echo "✅ Token still valid, no refresh needed"
              fi
    
  12. rekram1-node commented on Nov 24, 2025

    @rekram1-node
    Collaborator

    And then you are creating an auth.json file with ANTHROPIC_ACCESS_TOKEN and the other vars?

  13. thehaseebahmed commented on Nov 24, 2025

    @thehaseebahmed
    Author

    And then you are creating an auth.json file with ANTHROPIC_ACCESS_TOKEN and the other vars?

    Yes! That is what I'm doing. My bad, I could've pasted the whole workflow here. Here it goes:

    name: opencode-claudecode
    
    on:
      issue_comment:
        types: [created]
    
    jobs:
      opencode:
        if: |
          contains(github.event.comment.body, ' /claudecode') ||
          startsWith(github.event.comment.body, '/claudecode')
        runs-on: ubuntu-latest
        permissions:
          id-token: write
          contents: write
          pull-requests: write
          issues: write
        steps:
          - name: Checkout repository
            uses: actions/checkout@v4
    
          - name: Refresh OAuth tokens if needed
            env:
              GH_TOKEN: ${{ secrets.GH_PAT }}
            run: |
              CURRENT_TIME=$(($(date +%s) * 1000))
              TOKEN_EXPIRES=${{ secrets.ANTHROPIC_EXPIRES }}
              
              # Check if token needs refresh (expires in less than 1 hour)
              if [ $((TOKEN_EXPIRES - CURRENT_TIME)) -lt 3600000 ]; then
                echo "🔄 Token expiring soon, refreshing..."
                
                RESPONSE=$(curl -s -w "\n%{http_code}" -X POST https://console.anthropic.com/v1/oauth/token \
                  -H "Content-Type: application/json" \
                  -d "{
                    \"grant_type\": \"refresh_token\",
                    \"refresh_token\": \"${{ secrets.ANTHROPIC_REFRESH_TOKEN }}\",
                    \"client_id\": \"9d1c250a-e61b-44d9-88ed-5944d1962f5e\"
                  }")
                
                HTTP_CODE=$(echo "$RESPONSE" | tail -1)
                BODY=$(echo "$RESPONSE" | head -n -1)
                
                if [ "$HTTP_CODE" -eq "200" ]; then
                  echo "✅ Token refresh successful!"
                  
                  NEW_ACCESS=$(echo "$BODY" | jq -r '.access_token')
                  NEW_REFRESH=$(echo "$BODY" | jq -r '.refresh_token')
                  EXPIRES_IN=$(echo "$BODY" | jq -r '.expires_in')
                  NEW_EXPIRES=$(($(date +%s) * 1000 + EXPIRES_IN * 1000))
                  
                  # Update GitHub Secrets for future runs
                  echo "📝 Updating GitHub secrets..."
                  gh secret set ANTHROPIC_ACCESS_TOKEN --body "$NEW_ACCESS"
                  gh secret set ANTHROPIC_REFRESH_TOKEN --body "$NEW_REFRESH"
                  gh secret set ANTHROPIC_EXPIRES --body "$NEW_EXPIRES"
                  
                  echo "✅ Tokens refreshed and persisted"
                else
                  echo "❌ Token refresh failed with status $HTTP_CODE"
                  echo "$BODY"
                  exit 1
                fi
              else
                echo "✅ Token still valid, no refresh needed"
              fi
    
          - name: Write auth.json
            run: |
              mkdir -p ~/.local/share/opencode
              cat > ~/.local/share/opencode/auth.json <<EOF
              {
                "anthropic": {
                  "type": "oauth",
                  "refresh": "${{ secrets.ANTHROPIC_REFRESH_TOKEN }}",
                  "access": "${{ secrets.ANTHROPIC_ACCESS_TOKEN }}",
                  "expires": ${{ secrets.ANTHROPIC_EXPIRES }}
                }
              }
              EOF
              chmod 600 ~/.local/share/opencode/auth.json
    
          - name: Verify auth.json
            run: |
              echo "Auth file contents (masked):"
              jq 'with_entries(.value.refresh = "***" | .value.access = "***")' ~/.local/share/opencode/auth.json
    
          - name: Run opencode
            uses: sst/opencode/github@latest
            with:
              model: anthropic/claude-sonnet-4-5
    
  14. thehaseebahmed commented on Nov 24, 2025

    @thehaseebahmed
    Author

    Same behavior on a self-hosted runner but stuck at a different stage.

    Image
  15. thehaseebahmed commented on Nov 27, 2025

    @thehaseebahmed
    Author

    @rekram1-node This is starting to happen more and more frequently. Can you identify something wrong in this github workflow?

  16. rekram1-node commented on Nov 27, 2025

    @rekram1-node
    Collaborator

    yeah ill take a look when I get a chance

  17. thehaseebahmed commented on Nov 29, 2025

    @thehaseebahmed
    Author

    Just an update... This is happening for me, even with OpenCode provider so def. isn't something Claude Code Subscription specific. I wonder how more people are not facing it since I face it almost every day and multiple times throughout the day.

  18. rekram1-node commented on Nov 30, 2025

    @rekram1-node
    Collaborator

    Hmm weird, yeah haven't heard any other reports of this.

    Can you share what you are doing? Maybe you can export some logs from the github action?

    I think you could make them artifacts, the logs are stored at ~/.local/share/opencode/log/....

    Getting some logs would prolly nail this down

    Session share link may work too

  19. thehaseebahmed commented on Nov 30, 2025

    @thehaseebahmed
    Author

    @rekram1-node Any ideas how-to do it? Because when OpenCode step is stuck, it can only be cancelled or timeout and in both cases, any further steps do not run 🤔

  20. dhowe commented on Mar 22, 2026

    @dhowe

    same problem here with Qwen3.5:35b, 'Build' agent repeatedly hangs while working
    basically unusable, not sure how to debug

  21. cogni-ai-ee commented on Apr 11, 2026

    @cogni-ai-ee

    Same here:

    Sending message to opencode...
    

    when tried to use custom agent prompt, it stuck, default prompt works fine.

    If it's already sending some stream of data for longer amount of time, is there a flag to print it in realtime?

    Sessions:

    • ses_281665859ffemt9MPP4jm9PT6G (cancelled at 15m+)
    • ses_28153e2b2ffegp2cW1PqaUqlYa (cancelled at 2m+ to test)

    No errors in the logs, just info lines.
    Shorter prompts works fine, so I think the agent was just spending a lot of times, but the problem is that we don't see it, and it looks like it's stuck.
    Is there a way to enable stream of data being sent, to see what's doing?

  22. kenorb commented on Apr 17, 2026

    @kenorb

    Job stuck for 1.5h+ on Sending message to opencode..., does it mean it's eating tokens during that time, or it's just stuck?
    opencode session ses_264d286a3ffeFZ9CisDMEJdF6r
    Model: opencode/gpt-5-codex, then I've re-run using same prompt using opencode/gemini-3-flash, it worked.

  23. cogni-ai-ee commented on Apr 18, 2026

    @cogni-ai-ee

    Another hang with simple prompt.
    I've asked it to load a skill and tell about it.
    opencode session ses_25f478871ffewkRNNiUh464oku
    Sending message to opencode...
    (stuck for 1h+ mins, and it's not clear whether it's burning tokens or not for this simple query)

    --

    Another hang for 6h:
    opencode session ses_25ed9bf76ffesJrzZaTFGB14bh

    PROMPT: Load all skills and tell me what's them. Don't use ls to find it.
    Checking out new branch...
    Sending message to opencode...
    Error: The operation was canceled.
    

    I find opencode action not usable at this point as it happens at random and it's probably burning a lot of tokens.

  24. removed
    bugSomething isn't working
    on May 3, 2026
  25. cogni-ai-ee commented on May 13, 2026

    @cogni-ai-ee

    Another hung in this build.

    |  Shell    {"command":"printf \"%s\\n\" \"$PATH\"","description":"Check PATH environment variable"}
    [13:32:46.959] INFO (#181): loop {
      service: "session.prompt",
      "session.id": "ses_1de78b8a7ffedED7rxQh4nklxa",
      step: 9,
    }
    

    It's possible that it wrongly escaped some quotes? It's possible to set/override the timeout of each command, so it can re-try?

  26. cogni-ai-ee commented on May 13, 2026

    @cogni-ai-ee

    Another hung in this build.

    This relates to GH-16180 (Cloudflare 524 timeout) as confirmed from the logs.
    Potential fix in GH-16181 which was closed, please re-open.
    Problem happens on daily basis, 1/10 sessions become stuck for very long time.

  27. github-actions commented on Jul 19, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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