EBADF: bad file descriptor error on lstat for non-existent history.js file (Windows)

Resolved 💬 5 comments Opened Dec 24, 2025 by chashamm Closed Feb 27, 2026

Bug Description

Claude Code throws an unhandled promise rejection error referencing a file path that doesn't exist:

This error originated either by throwing inside of an async function without a catch block, 
or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason:
EBADF: bad file descriptor, lstat 'C:\Users\User\.claude\history.js'

Environment

  • OS: Windows 11
  • Claude Code Version: Latest (as of 2024-12-24)
  • Shell: Git Bash / PowerShell

Investigation Findings

  1. The error references history.js but only history.jsonl exists in the .claude directory
  2. The history.jsonl file is a regular file (not a symlink), ~474KB
  3. No references to history.js exist in user projects
  4. The file-history directory contains many UUID-named subdirectories (working normally)
  5. The file appears in directory listings but sometimes fails Get-Item calls (suggesting race condition)

Expected Behavior

Claude Code should not attempt to access history.js since the history file is history.jsonl

Actual Behavior

An unhandled promise rejection occurs with EBADF error on a non-existent file path

Possible Causes

  • Hardcoded or misconfigured file path referencing .js instead of .jsonl
  • Race condition in file descriptor management
  • Stale file handle from previous session
  • Windows-specific file locking issue

View original on GitHub ↗

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