[BUG] Claude Code SDK resume gives different session_id from the original session

Resolved 💬 5 comments Opened Sep 23, 2025 by paradite Closed Jan 9, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

When using Claude Code sdk with resume option from an existing session_id, the resumed session gets a different session_id.

I understand that similar issues has been reported, but I have managed to get a minimal reproduction solely focused on session id without having tools or generators for user prompts, showing that this issue is independent of generators or tools.

What Should Happen?

Claude Code sdk should return the same session_id

Error Messages/Logs

Steps to Reproduce

Here's the script to reproduce the issue on 1.0.120:

#!/usr/bin/env npx tsx

import { query } from '@anthropic-ai/claude-code';
import type { Options } from '@anthropic-ai/claude-code';

async function testDirectClaudeCodeWithStringPrompt() {
  console.log('🧪 Testing Claude Code SDK with String Prompt and Resume\n');

  try {
    // Step 1: Run initial request with maxTurns=2
    console.log(
      '1️⃣  Running initial Claude Code request with string prompt and maxTurns=2...',
    );

    const firstOptions: Options = {
      maxTurns: 2,
      model: 'claude-sonnet-4-20250514',
      includePartialMessages: false,
    };

    console.log(`   Options: ${JSON.stringify(firstOptions, null, 2)}`);

    const firstPrompt =
      'Create a simple hello-string.txt file with the content "Hello from first session"';

    let firstResult = '';
    let firstSessionId = '';

    const firstResponse = query({
      prompt: firstPrompt,
      options: firstOptions,
    });

    for await (const message of firstResponse) {
      console.log(`   📥 Full message: ${JSON.stringify(message, null, 2)}`);

      // Extract session ID from init message
      if (
        typeof message === 'object' &&
        message &&
        'type' in message &&
        message.type === 'system' &&
        'subtype' in message &&
        message.subtype === 'init' &&
        'session_id' in message
      ) {
        firstSessionId = message.session_id as string;
        console.log(`   📝 Init message received (sessionId: ${firstSessionId})`);
      }

      // Handle assistant messages with content
      if (
        typeof message === 'object' &&
        message &&
        'type' in message &&
        message.type === 'assistant' &&
        'message' in message &&
        message.message &&
        'content' in message.message
      ) {
        const content = message.message.content;
        const contentStr =
          typeof content === 'string' ? content : JSON.stringify(content);
        firstResult += contentStr;
        console.log(`   📝 Assistant message chunk: ${contentStr.substring(0, 100)}...`);
      }
    }

    console.log('✅ First request completed');
    console.log(`   Final Session ID: ${firstSessionId}`);
    console.log(`   Result length: ${firstResult.length} characters\n`);

    // Step 2: Resume with the session ID using string prompt
    console.log('2️⃣  Resuming session with explicit sessionId and string prompt...');

    const resumeOptions: Options = {
      maxTurns: 1,
      model: 'claude-sonnet-4-20250514',
      includePartialMessages: false,
      ...(firstSessionId && { resume: firstSessionId }), // Resume the session
    };

    console.log(`   Resume Options: ${JSON.stringify(resumeOptions, null, 2)}`);

    const resumePrompt =
      'What was the content I asked you to put in the hello-string.txt file?';

    let resumeResult = '';
    let resumeSessionId = '';

    const resumeResponse = query({
      prompt: resumePrompt,
      options: resumeOptions,
    });

    for await (const message of resumeResponse) {
      console.log(`   📥 Full resume message: ${JSON.stringify(message, null, 2)}`);

      // Extract session ID from init message
      if (
        typeof message === 'object' &&
        message &&
        'type' in message &&
        message.type === 'system' &&
        'subtype' in message &&
        message.subtype === 'init' &&
        'session_id' in message
      ) {
        resumeSessionId = message.session_id as string;
        console.log(`   📝 Init message received (sessionId: ${resumeSessionId})`);
      }

      // Handle assistant messages with content
      if (
        typeof message === 'object' &&
        message &&
        'type' in message &&
        message.type === 'assistant' &&
        'message' in message &&
        message.message &&
        'content' in message.message
      ) {
        const content = message.message.content;
        const contentStr =
          typeof content === 'string' ? content : JSON.stringify(content);
        resumeResult += contentStr;
        console.log(`   📝 Assistant message chunk: ${contentStr.substring(0, 100)}...`);
      }
    }

    console.log('✅ Resume request completed');
    console.log(`   Final Session ID: ${resumeSessionId}`);
    console.log(`   Result length: ${resumeResult.length} characters\n`);

    // Step 3: Compare results
    console.log('🔍 Comparison Results:');
    console.log(`   Original Session ID:     ${firstSessionId}`);
    console.log(`   Resume Session ID:       ${resumeSessionId}`);
    console.log(
      `   Session IDs Match:       ${firstSessionId === resumeSessionId ? '✅ YES' : '❌ NO'}`,
    );

    // Step 4: Test session memory
    console.log('\n🧠 Memory Test Results:');
    const memoryTestPassed = resumeResult
      .toLowerCase()
      .includes('hello from first session');
    console.log(
      `   Session remembers previous content: ${memoryTestPassed ? '✅ YES' : '❌ NO'}`,
    );

    if (memoryTestPassed) {
      console.log(
        '   💡 The resumed session correctly referenced the previous session content',
      );
    } else {
      console.log(
        '   ❌ The resumed session did not reference the previous session content',
      );
    }

    // Full response logging
    console.log('\n📄 Full First Session Response:');
    console.log(firstResult);
    console.log('\n📄 Full Resume Session Response:');
    console.log(resumeResult);

    // Summary
    console.log('\n📊 String Prompt Test Summary:');
    console.log(`   Original Session ID:     ${firstSessionId}`);
    console.log(`   Resume Session ID:       ${resumeSessionId}`);
    console.log(
      `   Session IDs Match:       ${firstSessionId === resumeSessionId ? '✅ YES' : '❌ NO'}`,
    );
    console.log(`   Session Memory Works:    ${memoryTestPassed ? '✅ YES' : '❌ NO'}`);

    if (firstSessionId === resumeSessionId && memoryTestPassed) {
      console.log(
        '✅ ALL TESTS PASSED - String prompt resume working correctly with session memory',
      );
    } else {
      console.log('❌ SOME TESTS FAILED:');
      if (firstSessionId !== resumeSessionId) {
        console.log('   - Session IDs do not match');
      }
      if (!memoryTestPassed) {
        console.log('   - Session memory test failed');
      }
    }
  } catch (error) {
    console.error('❌ String prompt test failed with error:', error);
  }
}

// Run the test
if (require.main === module) {
  testDirectClaudeCodeWithStringPrompt();
}

run npx tsx script.ts

output:

✅ First request completed
   Final Session ID: 2036c0a3-afe8-4053-b24b-5ceac4aae26f
   Result length: 497 characters

2️⃣  Resuming session with explicit sessionId and string prompt...
   Resume Options: {
  "maxTurns": 1,
  "model": "claude-sonnet-4-20250514",
  "includePartialMessages": false,
  "resume": "2036c0a3-afe8-4053-b24b-5ceac4aae26f"
}

✅ Resume request completed
   Final Session ID: d7ca99a9-b5cb-450b-af6e-ef8968b51475
   Result length: 51 characters

🔍 Comparison Results:
   Original Session ID:     2036c0a3-afe8-4053-b24b-5ceac4aae26f
   Resume Session ID:       d7ca99a9-b5cb-450b-af6e-ef8968b51475
   Session IDs Match:       ❌ NO

🧠 Memory Test Results:
   Session remembers previous content: ✅ YES
   💡 The resumed session correctly referenced the previous session content

📊 String Prompt Test Summary:
   Original Session ID:     2036c0a3-afe8-4053-b24b-5ceac4aae26f
   Resume Session ID:       d7ca99a9-b5cb-450b-af6e-ef8968b51475
   Session IDs Match:       ❌ NO
   Session Memory Works:    ✅ YES
❌ SOME TESTS FAILED:
   - Session IDs do not match

Claude Model

Sonnet (default)

Is this a regression?

No, this never worked

Last Working Version

_No response_

Claude Code Version

1.0.120

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

_No response_

View original on GitHub ↗

This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗