Skip to content

[BUG] Claude Code can't be spawned from node.js, but can be from python #771

@Flux159

Description

@Flux159

Environment

  • Platform (select one):
    • Anthropic API
  • Claude CLI version: 0.2.69 (Claude Code)
  • Operating System: Mac OS 15.3.1, Node v23.10.0
  • Terminal: Terminal App

Bug Description

Claude code doesn't run inside of node script.

Steps to Reproduce

Try running this node script that shells out to claude code using -p with stream-json:

const { exec } = require('child_process');
const { promisify } = require('util');
const execAsync = promisify(exec);

async function main() {
    try {
        const command = 'claude -p --dangerously-skip-permissions --output-format "stream-json" "ls -la"';
        console.log('Running command:', command);
        
        // Set a timeout to prevent hanging
        const timeout = 30000; // 30 seconds
        
        // Create a promise that rejects after the timeout
        const timeoutPromise = new Promise((_, reject) => {
            setTimeout(() => {
                reject(new Error(`Command timed out after ${timeout}ms`));
            }, timeout);
        });
        
        // Run the command with a timeout
        const result = await Promise.race([
            execAsync(command),
            timeoutPromise
        ]);
        
        console.log('Command completed successfully');
        console.log('stdout:', result.stdout);
        if (result.stderr) console.log('stderr:', result.stderr);
        
    } catch (error) {
        console.error('Error:', error.message);
    }
}

main(); 

Instead of returning streaming json outputs, it stalls.

Now try running with python:

import subprocess
import json
import sys
from datetime import datetime

def main():
    print(f"Starting Claude test at {datetime.now()}")
    
    # Command to run
    cmd = ['claude', '-p', '--dangerously-skip-permissions', '--output-format', 'stream-json', 'ls -la']
    
    try:
        # Run the command with a timeout
        print("Running command:", ' '.join(cmd))
        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,
            timeout=30  # 30 second timeout
        )
        
        print("\nExit code:", result.returncode)
        
        if result.stdout:
            print("\nStdout:")
            print(result.stdout)
            
            # Try to parse JSON output
            try:
                for line in result.stdout.splitlines():
                    if line.strip():
                        json_data = json.loads(line)
                        print("\nParsed JSON:")
                        print(json.dumps(json_data, indent=2))
            except json.JSONDecodeError as e:
                print("Failed to parse JSON:", e)
        
        if result.stderr:
            print("\nStderr:")
            print(result.stderr)
            
    except subprocess.TimeoutExpired:
        print("Command timed out after 30 seconds")
    except subprocess.CalledProcessError as e:
        print("Command failed with exit code:", e.returncode)
        print("Stderr:", e.stderr)
    except Exception as e:
        print("Error:", str(e))

if __name__ == "__main__":
    main() 

The python script can exec perfectly fine.

Expected Behavior

Node apps that use exec or spawn should be able to get results from claude code.

Actual Behavior

Node apps stall and don't return any results, yet python & shell works fine.

Additional Context

I tried with exec, spawn, using the same env vars, etc. and nothing worked in Node. Is claude code mutating a the node environment in some way such that subprocesses don't work correctly?

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions