OpenCode Github Agent Stuck! #3076

Open
opened 2026-02-16 17:38:30 -05:00 by yindo · 16 comments
Owner

Originally created by @thehaseebahmed on GitHub (Nov 23, 2025).

Originally assigned to: @rekram1-node on GitHub.

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

Originally created by @thehaseebahmed on GitHub (Nov 23, 2025). Originally assigned to: @rekram1-node on GitHub. ### 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 <img width="1080" height="2410" alt="Image" src="https://github.com/user-attachments/assets/5dd95a66-aed0-422c-906b-cd04d1d3c5cc" /> ### Operating System ubuntu-latest ### Terminal Github Actions
yindo added the bug label 2026-02-16 17:38:30 -05:00
Author
Owner

@github-actions[bot] commented on GitHub (Nov 23, 2025):

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

  • #3846: No response to user input - Similar issue where UI becomes unresponsive and doesn't listen to input
  • #4073: Hanging During Agent Tasks - Agent work hangs and doesn't respond to ESC/CTRL-C, similar hanging behavior
  • #4319: Strangely enough, it always gets stuck or encounters an exception during task execution - Similar stuck behavior with agents not progressing
  • #2438: Seems to freeze on "working..." with no changes - Related freezing/hanging issue

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

@github-actions[bot] commented on GitHub (Nov 23, 2025): This issue might be a duplicate of existing issues. Please check: - #3846: No response to user input - Similar issue where UI becomes unresponsive and doesn't listen to input - #4073: Hanging During Agent Tasks - Agent work hangs and doesn't respond to ESC/CTRL-C, similar hanging behavior - #4319: Strangely enough, it always gets stuck or encounters an exception during task execution - Similar stuck behavior with agents not progressing - #2438: Seems to freeze on "working..." with no changes - Related freezing/hanging issue Feel free to ignore if your specific case differs from these issues.
Author
Owner

@rekram1-node commented on GitHub (Nov 23, 2025):

/oc test

@rekram1-node commented on GitHub (Nov 23, 2025): /oc test
Author
Owner

@opencode-agent[bot] commented on GitHub (Nov 23, 2025):

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

@opencode-agent[bot] commented on GitHub (Nov 23, 2025): 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. <a href="https://opencode.ai/s/ZizzA6uM"><img width="200" alt="New%20session%20-%202025-11-24T00%3A56%3A57.417Z" src="https://social-cards.sst.dev/opencode-share/TmV3IHNlc3Npb24gLSAyMDI1LTExLTI0VDAwOjU2OjU3LjQxN1o=.png?model=opencode/glm-4.6&version=1.0.106&id=ZizzA6uM" /></a> [opencode session](https://opencode.ai/s/ZizzA6uM)&nbsp;&nbsp;|&nbsp;&nbsp;[github run](/sst/opencode/actions/runs/19620112147)
Author
Owner

@rekram1-node commented on GitHub (Nov 23, 2025):

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

@rekram1-node commented on GitHub (Nov 23, 2025): thats made up ^ lol but ill look into it, ofc cant replicate tho
Author
Owner

@rekram1-node commented on GitHub (Nov 23, 2025):

What provider are u using?

@rekram1-node commented on GitHub (Nov 23, 2025): What provider are u using?
Author
Owner

@thehaseebahmed commented on GitHub (Nov 23, 2025):

What provider are u using?

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

@thehaseebahmed commented on GitHub (Nov 23, 2025): > What provider are u using? I'm using Claude Code Subscription. I can try with OpenCode Zen as well if that helps.
Author
Owner

@rekram1-node commented on GitHub (Nov 23, 2025):

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

@rekram1-node commented on GitHub (Nov 23, 2025): If you are using claude code subscription how are you completing the oauth exchange in CI?
Author
Owner

@thehaseebahmed commented on GitHub (Nov 23, 2025):

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
@thehaseebahmed commented on GitHub (Nov 23, 2025): > 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 ```
Author
Owner

@rekram1-node commented on GitHub (Nov 24, 2025):

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

@rekram1-node commented on GitHub (Nov 24, 2025): And then you are creating an auth.json file with ANTHROPIC_ACCESS_TOKEN and the other vars?
Author
Owner

@thehaseebahmed commented on GitHub (Nov 24, 2025):

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
@thehaseebahmed commented on GitHub (Nov 24, 2025): > 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 ```
Author
Owner

@thehaseebahmed commented on GitHub (Nov 24, 2025):

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

Image
@thehaseebahmed commented on GitHub (Nov 24, 2025): Same behavior on a self-hosted runner but stuck at a different stage. <img width="1080" height="2267" alt="Image" src="https://github.com/user-attachments/assets/66b2c019-f407-440d-941d-12ec4938b060" />
Author
Owner

@thehaseebahmed commented on GitHub (Nov 27, 2025):

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

@thehaseebahmed commented on GitHub (Nov 27, 2025): @rekram1-node This is starting to happen more and more frequently. Can you identify something wrong in this github workflow?
Author
Owner

@rekram1-node commented on GitHub (Nov 27, 2025):

yeah ill take a look when I get a chance

@rekram1-node commented on GitHub (Nov 27, 2025): yeah ill take a look when I get a chance
Author
Owner

@thehaseebahmed commented on GitHub (Nov 29, 2025):

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.

@thehaseebahmed commented on GitHub (Nov 29, 2025): 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.
Author
Owner

@rekram1-node commented on GitHub (Nov 29, 2025):

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

@rekram1-node commented on GitHub (Nov 29, 2025): 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
Author
Owner

@thehaseebahmed commented on GitHub (Nov 30, 2025):

@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 🤔

@thehaseebahmed commented on GitHub (Nov 30, 2025): @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 🤔
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#3076