claude-code icon indicating copy to clipboard operation
claude-code copied to clipboard

Error: Raw mode is not supported on the current process.stdin, which Ink uses as input stream by default.

Open pierrekttipay opened this issue 8 months ago • 11 comments

I am looking to run claude on a github actions CICD pipeline to review my code automatically on PRs. I am using the command line: claude -p "my prompt" --print but no luck.

Error: Raw mode is not supported on the current process.stdin, which Ink uses as input stream by default.
Read about how to prevent this error on https://github.com/vadimdemedes/ink/#israwmodesupported
    at handleSetRawMode (file:///opt/hostedtoolcache/node/22.14.0/x64/lib/node_modules/@anthropic-ai/claude-code/cli.js:4[7](https://github.com/kttipay/banking-service/actions/runs/13747645371/job/38444607184#step:5:8)6:2045)
    at file:///opt/hostedtoolcache/node/22.14.0/x64/lib/node_modules/@anthropic-ai/claude-code/cli.js:486:2000
    at wK (file:///opt/hostedtoolcache/node/22.14.0/x64/lib/node_modules/@anthropic-ai/claude-code/cli.js:77:21381)
    at pV (file:///opt/hostedtoolcache/node/22.14.0/x64/lib/node_modules/@anthropic-ai/claude-code/cli.js:77:40838)
    at file:///opt/hostedtoolcache/node/22.14.0/x64/lib/node_modules/@anthropic-ai/claude-code/cli.js:77:39053
    at UI1 (file:///opt/hostedtoolcache/node/22.14.0/x64/lib/node_modules/@anthropic-ai/claude-code/cli.js:71:22715)
    at Immediate.zI1 [as _onImmediate] (file:///opt/hostedtoolcache/node/22.14.0/x64/lib/node_modules/@anthropic-ai/claude-code/cli.js:71:23127)
    at process.processImmediate (node:internal/timers:491:21)

  ERROR Raw mode is not supported on the current process.stdin, which Ink uses
       as input stream by default.
       Read about how to prevent this error on
       https://github.com/vadimdemedes/ink/#israwmodesupported
 - Read about how to prevent this error on
   https://github.com/vadimdemedes/ink/#israwmodesupported
 -handleSetRawM (file:///opt/hostedtoolcache/node/22.14.0/x64/lib/node_modules/
  ode          @anthropic-ai/claude-code/cli.js:476:2045)
 - (file:///opt/hostedtoolcache/node/22.14.0/x64/lib/node_modules/@anthropic-ai
  /claude-code/cli.js:4[8](https://github.com/kttipay/banking-service/actions/runs/13747645371/job/38444607184#step:5:9)6:2000)
 -wK (file:///opt/hostedtoolcache/node/22.14.0/x64/lib/node_modules/@anthropic-
    ai/claude-code/cli.js:77:21381)
 -pV (file:///opt/hostedtoolcache/node/22.14.0/x64/lib/node_modules/@anthropic-
    ai/claude-code/cli.js:77:40838)
 - (file:///opt/hostedtoolcache/node/22.14.0/x64/lib/node_modules/@anthropic-ai
  /claude-code/cli.js:77:3[9](https://github.com/kttipay/banking-service/actions/runs/13747645371/job/38444607184#step:5:10)053)
 -UI1 (file:///opt/hostedtoolcache/node/22.14.0/x64/lib/node_modules/@anthropic
     -ai/claude-code/cli.js:71:22715)
 -Immediate.z (file:///opt/hostedtoolcache/node/22.14.0/x64/lib/node_modules/@a
  1          nthropic-ai/claude-code/cli.js:71:23127)
 - process.processImmediate (node:internal/timers:491:21)

pierrekttipay avatar Mar 09 '25 10:03 pierrekttipay

@pierrekttipay What did you try? I am trying the same but I am also facing the same issue. I have tried different approaches, even using a Docker image. Do you think we can collaborate?

tcorral avatar Mar 09 '25 17:03 tcorral

@tcorral I am trying to setup github action to analyse the current pull request diff and write an automated review about the code.

name: review-on-pr-to-main

on:
  pull_request:
    branches:
      - main

jobs:
  review:
    name: Review
    runs-on: ubuntu-20.04
    steps:
      - uses: actions/checkout@v4
      - uses: buildjet/setup-node@v3
        with:
          node-version: lts/*
          check-latest: true
      - run: npm install -g @anthropic-ai/claude-code
      - name: run claude
        id: run_claude
        env:
          TITLE: "${{github.event.pull_request.title}}"
        run: |
          claude -p "This codebase is.... I want you to perform a diff against the main branch and conduct a thorough code review for correctness, consistency, performance, scalability, security, and code quality. The current pull request title is: $TITLE" --print
      - name: Put Review in Env Var
        env:
          REVIEW: ${{join(steps.run_claude.outputs.*, '\n')}}
        run: |
          echo "REVIEW<<EOF" >> $GITHUB_ENV
          echo "$REVIEW" >> $GITHUB_ENV
          echo "EOF" >> $GITHUB_ENV
      - name: Post Review to GitHub PR
        uses: mshick/add-pr-comment@v2
        with:
          allow-repeats: true
          repo-token: ${{ secrets.GITHUB_TOKEN }}
          repo-token-user-login: "github-actions[bot]"
          message: ${{ env.REVIEW }}

I think we need the claude-code core team to get involve. This package is fundamentally an interactive tool which makes it extremely limited. The -p option is not doing enough in my opinion. The -p should really avoid any interactive tooling to bootstrap. At the moment it seems that -p is just a way to auto exit the interactive tool after the first answer. The --print doesn't do anything it seems (maybe it's redundant with the -p, I couldn't find much doc about it)

pierrekttipay avatar Mar 09 '25 21:03 pierrekttipay

Trying to integrate Claude Code to our CI/CD pipeline today as well (in a GitHub action) and running into the same error. Need a way to run without requiring interaction.

Dan-Wuensch avatar Mar 11 '25 15:03 Dan-Wuensch

I tried the following:

workflow.yml

name: Claude Code Automation

# Define explicit permissions
permissions:
  contents: write
  issues: write
  pull-requests: write

on:
  issues:
    types: [labeled]
jobs:
  claude-issue-processor:
    runs-on: ubuntu-latest
    if: contains(github.event.issue.labels.*.name, 'claude-code')
    steps:
      - name: Parse issue description
        id: parse-description
        uses: actions/github-script@v7
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            // Get issue details
            const issue = context.payload.issue;
            if (!issue || !issue.body) {
              core.setFailed('No issue description found');
              return;
            }
            
            // Debug: Log issue body
            console.log('Processing issue description');
            
            // Simple markdown parser for issue descriptions
            function parseMarkdown(markdown) {
              // Function to convert basic markdown to plain text
              function markdownToPlainText(text) {
                return text
                  // Remove code blocks
                  .replace(/```[\s\S]*?```/g, '')
                  // Remove inline code
                  .replace(/`([^`]+)`/g, '$1')
                  // Remove bold/italic
                  .replace(/\*\*([^*]+)\*\*/g, '$1')
                  .replace(/\*([^*]+)\*/g, '$1')
                  .replace(/__([^_]+)__/g, '$1')
                  .replace(/_([^_]+)_/g, '$1')
                  // Handle lists by replacing bullets with spaces
                  .replace(/^\s*[*-]\s+/gm, '')
                  .replace(/^\s*\d+\.\s+/gm, '')
                  // Normalize whitespace
                  .replace(/\n+/g, ' ')
                  .replace(/\s+/g, ' ')
                  .trim();
              }
              
              // Extract sections (split by ## headings)
              const sections = {};
              const sectionRegex = /##\s+([^\n]+)([^#]*)/g;
              let match;
              
              while ((match = sectionRegex.exec(markdown)) !== null) {
                const sectionName = match[1].trim();
                const sectionContent = markdownToPlainText(match[2]);
                sections[sectionName] = sectionContent;
              }
              
              return sections;
            }
            
            try {
              // Extract sections from markdown
              const parsedSections = parseMarkdown(issue.body);
              
              // Debug: Log parsed sections
              console.log('Parsed sections:', JSON.stringify(parsedSections, null, 2));
              
              // Format the result as a single string
              let formattedResult = '';
              for (const [section, content] of Object.entries(parsedSections)) {
                formattedResult += `${section}: ${content} `;
              }
              
              // Trim extra spaces
              formattedResult = formattedResult.trim();
              
              // Add a comment to the issue with the parsed result
              await github.rest.issues.createComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: issue.number,
                body: `**Parsed Issue Description:**\n\n${formattedResult}`
              });
              
              // Set output for use in subsequent steps
              core.setOutput('parsed_description', formattedResult);
              
              console.log('Successfully parsed issue description');
            } catch (error) {
              console.error('Error details:', error);
              core.setFailed(`Error parsing issue description: ${error.message}`);
            }
  
      - name: Log parsed result
        run: |
          echo "Parsed description: ${{ steps.parse-description.outputs.parsed_description }}"

      - uses: actions/checkout@v4
      
      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install Claude Code
        run: npm install -g @anthropic-ai/claude-code
      
      - name: Install Expect
        run: sudo apt-get update && sudo apt-get install -y expect

      - name: Ensure script is executable
        run: chmod +x .github/workflows/claude-script.exp

      - name: Create and Switch to a New Branch
        run: |
          # Extract issue number and title
          ISSUE_NUMBER="${{ github.event.issue.number }}"
          ISSUE_TITLE="${{ github.event.issue.title }}"

          # Format title: lowercase, replace spaces with dashes, remove special characters
          SAFE_TITLE=$(echo "$ISSUE_TITLE" | tr '[:upper:]' '[:lower:]' | tr ' ' '-' | tr -cd '[:alnum:]-')

          # Set branch name
          BRANCH_NAME="claude-issue-${ISSUE_NUMBER}-${SAFE_TITLE}"
          echo "Creating branch: $BRANCH_NAME"

          git fetch origin
          git checkout -b "$BRANCH_NAME"
          git push origin "$BRANCH_NAME"

          # Save branch name for later steps
          echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV

      - name: Execute Claude Code
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
        run: |
          expect .github/workflows/claude-script.exp "${{ steps.parse-description.outputs.parsed_description }}"

      - name: Check for changes
        id: git-check
        run: |
          git status --porcelain
          echo "HAS_CHANGES=$(if git status --porcelain | grep .; then echo "true"; else echo "false"; fi)" >> $GITHUB_ENV
        
      - name: Commit changes
        if: env.HAS_CHANGES == 'true'
        run: |
          git config --local user.email "[email protected]"
          git config --local user.name "GitHub Action"
          git add .
          git commit -m "Claude Code changes for issue #${{ github.event.issue.number }}"
          git push origin ${{ env.BRANCH_NAME }}

      - name: Create Pull Request
        if: env.HAS_CHANGES == 'true'
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
            ISSUE_NUMBER="${{ github.event.issue.number }}"
            ISSUE_TITLE="${{ github.event.issue.title }}"

            # Create a pull request
            gh pr create \
                --base main \
                --head ${{ env.BRANCH_NAME }} \
                --title "Fix #$ISSUE_NUMBER: $ISSUE_TITLE" \
                --body "This PR resolves issue #$ISSUE_NUMBER by applying the requested changes using Claude."

      - name: Report no changes
        if: env.HAS_CHANGES == 'false'
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          gh issue comment ${{ github.event.issue.number }} --body "Claude Code was executed but no changes were made to the codebase. This might be because Claude couldn't understand the request or no changes were needed."

claude-script.exp

#!/usr/bin/expect -f
log_user 1   ;# Enable logging to stdout

set timeout 800

# Get the command-line argument (the prompt)
set prompt [lindex $argv 0]

# Configure Claude Code first
spawn claude config add allowedTools Edit
expect eof

spawn claude config add allowedTools Replace
expect eof

# Launch Claude with the prompt
spawn claude -p "$prompt"

# Wait for Claude to complete its work
# Look for more reliable completion indicators
expect {
    "Based on my examination of the code" { puts "Claude completed the changes successfully" }
    timeout { puts "Claude took too long to respond"; exit 1 }
}

# Send confirmation if needed
send "yes\r"

# Allow time for changes to complete
sleep 10

# Send Ctrl+D to exit Claude
send "\x04"
expect eof

The problem is that the first two commands run without requiring interaction and the last one gets stuck.

@ashwin-ant Are there any plans to add a non-interactive argument so it can be used in a similar way as you can use Aider?

tcorral avatar Mar 12 '25 16:03 tcorral

I have had a similar issue with the following no frills dockerfile

FROM ubuntu:latest
USER root
WORKDIR /home/app
RUN apt-get update
RUN apt-get -y install curl gnupg git python3 python3-pip
RUN curl -sL https://deb.nodesource.com/setup_18.x  | bash -
RUN apt-get -y install nodejs
RUN npm install -g @anthropic-ai/claude-code
# Set environment variables for authentication
ENV ANTHROPIC_API_KEY=""
VOLUME /home/app/projects
ENTRYPOINT ["claude"]`

error returned which is the same as above:

╭────────────────────────────────────────────╮
│ ✻ Welcome to Claude Code research preview! │
╰────────────────────────────────────────────╯

Error: Raw mode is not supported on the current process.stdin, which Ink uses as input stream by default.
Read about how to prevent this error on https://github.com/vadimdemedes/ink/#israwmodesupported
    at handleSetRawMode (file:///usr/lib/node_modules/@anthropic-ai/claude-code/cli.js:478:2045)
    at file:///usr/lib/node_modules/@anthropic-ai/claude-code/cli.js:488:2000
    at vK (file:///usr/lib/node_modules/@anthropic-ai/claude-code/cli.js:81:21381)
    at VC (file:///usr/lib/node_modules/@anthropic-ai/claude-code/cli.js:81:40838)
    at file:///usr/lib/node_modules/@anthropic-ai/claude-code/cli.js:81:39053
    at MB1 (file:///usr/lib/node_modules/@anthropic-ai/claude-code/cli.js:75:22703)
    at Immediate.UB1 [as _onImmediate] (file:///usr/lib/node_modules/@anthropic-ai/claude-code/cli.js:75:23115)
    at process.processImmediate (node:internal/timers:476:21)

  ERROR Raw mode is not supported on the current process.stdin, which Ink uses
       as input stream by default.
       Read about how to prevent this error on
       https://github.com/vadimdemedes/ink/#israwmodesupported

 - Read about how to prevent this error on
   https://github.com/vadimdemedes/ink/#israwmodesupported
 -handleSetRawMo (file:///usr/lib/node_modules/@anthropic-ai/claude-code/cli.js
  e             :478:2045)
 -  (file:///usr/lib/node_modules/@anthropic-ai/claude-code/cli.js:488:2000)
 - vK (file:///usr/lib/node_modules/@anthropic-ai/claude-code/cli.js:81:21381)
 - VC (file:///usr/lib/node_modules/@anthropic-ai/claude-code/cli.js:81:40838)
 -  (file:///usr/lib/node_modules/@anthropic-ai/claude-code/cli.js:81:39053)
 - MB1 (file:///usr/lib/node_modules/@anthropic-ai/claude-code/cli.js:75:22703)
 -Immediate.UB (file:///usr/lib/node_modules/@anthropic-ai/claude-code/cli.js:7
              5:23115)
 - process.processImmediate (node:internal/timers:476:21)

Perhaps this is a simpler setup to debug for a similar error. Happy to create a separate issue if required.

teamm8 avatar Mar 12 '25 22:03 teamm8

@tcorral I am experimenting with your solution. I face another issue which is

Invalid API key · Please run /login

It seems claude code requires login via the browser the first time you launch the claude command. This browser login interaction creates a "Claude Code API key" automatically and do allow reading the full key.

Since I am trying to run claude-code on a cicd, I do not have the option to open a browser and login, thus I do not have a valid key to use claude on cicd.

pierrekttipay avatar Mar 19 '25 21:03 pierrekttipay

Fwiw I hit this when running locally, not CI. It happened when I piped input to claude. It worked when I didn't pipe, but strangely then the next time I piped it started working again 🤷

pokey avatar Apr 03 '25 19:04 pokey

I suspect this only manifests any time running claude results in a "box" which requires input before continuing (e.g. approving MCP servers, or confirming you trust running claude in a directory)

thejcannon avatar Apr 08 '25 16:04 thejcannon

I suspect this only manifests any time running claude results in a "box" which requires input before continuing (e.g. approving MCP servers, or confirming you trust running claude in a directory)

Ohh that seems definitely like it could have been it. I ran it a few times with pipe and hit this every time, and pretty sure it was first time I ran it in some repo, then when I ran without pipe I probably hit trust button and then reran again with pipe and it worked

pokey avatar Apr 09 '25 22:04 pokey

This is preventing our engineering dept from switching from Goose to Claude for some CI/CD workloads at the moment

Usage: "cat instructions.txt | claude --dangerously-skip-permissions"

(in a safe containerized environment)

Dan-Wuensch avatar Apr 10 '25 02:04 Dan-Wuensch

I'm encountering sth similar, I'm using claude code in E2B, but I cannot get output. Are there any updates about this issue?

HaiyiMei avatar May 29 '25 15:05 HaiyiMei

I've encountered the same issue whenever I pipe to Claude on a new project or using a new Claude command. I then run claude to start an interactive session and it prompts you to confirm that you trust the current codebase. Once you say "Yes" you can exit and successfully run the pipe command.

It makes sense that you might encounter this in CI where it's always a "new" project for Claude. You could try running claude --permission-mode bypassPermissions as a step in your CI. See https://docs.anthropic.com/en/docs/claude-code/iam#permission-modes

scott82anderson avatar Jul 23 '25 03:07 scott82anderson

Thanks @scott82anderson it worked.

I ran claude code in the CICD using: expect .github/workflows/claude-script.exp "$PROMPT"

claude-code.exp

#!/usr/bin/expect -f
log_user 1   ;# Enable logging to stdout

set timeout 800

# Get the command-line argument (the prompt)
set prompt [lindex $argv 0]

# Configure Claude Code first
spawn claude config add allowedTools Edit
expect eof

spawn claude config add allowedTools Replace
expect eof

# Launch Claude with the prompt
spawn claude --permission-mode bypassPermissions -p "$prompt"

# Wait for Claude to complete its work
# Look for more reliable completion indicators
expect {
    eof {
        puts "Claude process finished (EOF reached)"
    }
    timeout {
        puts "Claude took too long to respond"
        exit 1
    }
}

pierrekttipay avatar Jul 28 '25 01:07 pierrekttipay

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.

github-actions[bot] avatar Aug 04 '25 14:08 github-actions[bot]