[BUG] Claude Code consistently creates files with Windows line endings on Linux systems

Open 💬 42 comments Opened Jul 1, 2025 by pm0code
💡 Likely answer: A maintainer (blois, collaborator) responded on this thread — see the highlighted reply below.

Description:
Despite being on Ubuntu Linux and explicitly adding instructions to CLAUDE.md, Claude Code continues to
create shell scripts and text files with Windows line endings (CRLF) instead of Unix line endings (LF).
This causes "No such file or directory" errors when executing scripts.

Steps to Reproduce:

  1. Use Claude Code on Linux (Ubuntu 24.04)
  2. Ask it to create any shell script
  3. Try to execute the script with ./script.sh
  4. Get error: "unable to execute ./script.sh: No such file or directory"

Expected Behavior:
Files should be created with Unix line endings (\n) on Linux systems

Actual Behavior:
Files are created with Windows line endings (\r\n), requiring manual conversion with sed -i 's/\r$//'

Environment:

  • OS: Ubuntu 24.04.2 LTS
  • Kernel: 6.11.0-26-generic
  • Claude Code version: [your version]

Impact:

  • Breaks workflow repeatedly
  • Requires manual intervention for every script
  • Even after adding explicit instructions to CLAUDE.md, the issue persists

Suggested Fix:
Claude Code should detect the OS and use appropriate line endings automatically, or at minimum respect
the CLAUDE.md instructions.

View original on GitHub ↗

42 Comments

blois collaborator · 1 year ago

Claude attempts to find some files in the repo then looks at the line endings for those files. Is it possible that your repo has some files with carriage return newlines?

pm0code · 11 months ago

No, because before every git, it cleans up all of those. my issue is that even when it is checking stuff and writes a script, it always has to come back with an error that "the file has windows endings. let me fix that".

I am surprised for two reasons at least:

  1. why is this happening in the first place? it is so easy to understand what environment you are running in and make an adjustment from the start.
  2. this is supposed to be an AI system, why don't you learn from your mistakes and stop repeating them over and over again?
JerryLife · 11 months ago

The same thing happens to me when running ssh Linux terminal on Windows. The claude code starting from remote keeps corrupting my bash script by inserting Windows line endings.

Krashnicov · 11 months ago

Happens here too, very frustrating.

kshy0519 · 11 months ago

Happens here too. Hot fix needed!
Even after adding explicit instructions to CLAUDE.md, the issue persists.

phelbas · 11 months ago

I just asked Claude and he confirmed it:

⏺ Bash(file backend/backup_stuff/*.sh)
⎿  backend/backup_stuff/backup_main.sh: Bourne-Again shell script text executable, ASCII text
backend/backup_stuff/filesystem_backup.sh: Bourne-Again shell script text executable, ASCII text
backend/backup_stuff/mysql_backup.sh: Bourne-Again shell script text executable, ASCII text
… +1 line (ctrl+r to expand)

⏺ Fixed! You're absolutely right - this is a Claude Code bug where I create files with Windows CRLF line endings even on macOS/Unix systems.
The files now have proper Unix line endings and should work correctly when you transfer them to your metal server.

This explains why you keep running into this issue - it's happening whenever Claude Code creates shell scripts or other text files that
need Unix line endings.

OstiumAxioma · 10 months ago

Similar issue here. It does the opposite on Windows Powershell environment. Not only it do LF instead of CRLF on Windows, none of its Powershell or Bash command and run successfully in Powershell environment.

fsc-eriker · 10 months ago

I can't say I see this _consistently_ but from time to time, I have had Claude create files with DOS carriage returns on a Mac. The problem is exacerbated by the fact that Claude doesn't seem to understand what the error message means (python3\r: No such file or directory)

ashesfall · 9 months ago

This is pretty bad - I have now dedicated a substantial portion of CLAUDE.md to insisting it stop doing this, and it won't stop doing this.

maxhaice2 · 8 months ago

Hi, thank you for such a good job, I use claude code inside terminal. Same here

ondrejtucny · 8 months ago

The exact opposite happens on Windows, very frustrating.

scytaskin · 7 months ago

Same thing happens to me and it makes looking at changes to existing files in our repo a pain. Because of the line ending difference when claude uses the write tool every line is seen as new, so the diff view doesnt work properly.

github-actions[bot] · 6 months ago

This issue has been inactive for 30 days. If the issue is still occurring, please comment to let us know. Otherwise, this issue will be automatically closed in 30 days for housekeeping purposes.

u011 · 6 months ago

THe issue is active, do not autoclose

wolfgangihloff · 6 months ago

Can confirm too, it seems when working with a codebase from colleagues that work on Windows it somehow gets anchored into windows mode, but I cannot tell which files "trigger" it.

fsc-eriker · 6 months ago

@wolfgangihloff I see this on systems where nobody has been near Windows for many years, it doesn't seem to be a case of contagion, just that it occasionally slips into this randomly.

wolfgangihloff · 6 months ago

Fair point, I can only report my take

  • not had this occur once on projects I started and created on MacOSX
  • not had it with random number of OSS projects cloned from Github
  • started working with some Windows devs on shared docker containers, there

it happens regular the last few days, only in that project

Happy to investigate more, for now just wanted to encourage not to close
this issue as another older one was closed.

On Fri, Jan 9, 2026 at 10:00 AM fsc-eriker @.***> wrote:

fsc-eriker left a comment (anthropics/claude-code#2805) <https://github.com/anthropics/claude-code/issues/2805#issuecomment-3728192427> @wolfgangihloff <https://github.com/wolfgangihloff> I see this on systems where nobody has been near Windows for many years, it doesn't seem to be a case of contagion, just that it occasionally slips into this randomly. — Reply to this email directly, view it on GitHub <https://github.com/anthropics/claude-code/issues/2805#issuecomment-3728192427>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AABHXABEOA72EN6OZ3NQUJ34F532FAVCNFSM6AAAAACARM3MPOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTOMRYGE4TENBSG4> . You are receiving this because you were mentioned.Message ID: @.***>
mcraveiro · 5 months ago

I keep having this issue. I got a script that I run that dos2unix the entire code base but it is a pain to have to run it periodically.

kalupa · 5 months ago

I'd love to see this improved in the Write tool. I also have seen it just randomly switch on windows file endings despite no files having them

mcraveiro · 5 months ago

Yes, I asked Claude about this and it said it was writing with UNIX line endings but some other tool in the pipeline was introducing the windows line endings. So it is probably the write tool.

robertsonh · 5 months ago

I have never run into this on any of my machines but a brand new NixOS install started doing it. Project has never touched a windows box. Very odd. Seems to be the write tool but claude doesn't know why.

rolandinus · 4 months ago

Never had this issue before but since yesterday having the same problem since today

piekstra · 4 months ago

Workaround: PostToolUse hook to auto-strip CRLF

Still hitting this on macOS (Sequoia 15.6, Apple Silicon, Claude Code 2.1.45). The Write tool produces CRLF line endings on every file it creates, which breaks shell scripts immediately (bad interpreter: /bin/bash^M).

Fix

Add a PostToolUse hook to ~/.claude/settings.json that strips \r after every Write/Edit:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "FILE=$(cat | jq -r '.tool_input.file_path // empty') && [ -n \"$FILE\" ] && [ -f \"$FILE\" ] && sed -i '' $'s/\\r$//' \"$FILE\"",
            "timeout": 30
          }
        ]
      }
    ]
  }
}

Merge this into your existing ~/.claude/settings.json if you have other settings there.

Note for Linux: change sed -i '' to sed -i (GNU sed doesn't take the empty string argument).

How it works

  • The PostToolUse hook fires after every successful Write or Edit tool call
  • It reads the tool input JSON from stdin, extracts file_path with jq
  • Strips carriage returns in-place with sed
  • Requires jq installed (brew install jq / apt install jq)

Tested and confirmed working — files come out with clean LF line endings. The hook fires within the same session it's configured in (no restart needed if you add it while running, though first Write may miss it depending on timing).

This should really be fixed in the Write/Edit tool itself though — there's no reason to produce CRLF on macOS or Linux.

fsc-eriker · 4 months ago
cat | jq -r '.tool_input.file_path // empty'

Ding! That's a useless use of cat

More seriously, perhaps there should be a check to make sure you never end up wrecking binary files (more likely if you work with audio or images etc)

slickroot · 4 months ago

I hade this problem, is there a hacky fix at least we can use in the meantime?

fsc-eriker · 4 months ago

@slickroot The comment by piekstra from 3 weeks ago has a proposed workaround. For my part I use an Awk script which also checks line lengths and verifies that the last line does not lack a newline.

Blackclaws · 4 months ago

This might be related to the type of shell you are using. See the bug I just opened. I'm not sure if its the same underlying reason but I started getting CRLF after switching to wayland and kitty as a terminal, setting the TERM variable to xterm-256color fixed it.

fsc-eriker · 4 months ago

@Blackclaws Maybe explicitly link to https://github.com/anthropics/claude-code/issues/33910, it is not trivial to find out which bug you are referring to.

Blackclaws · 4 months ago
@Blackclaws Maybe explicitly link to #33910, it is not trivial to find out which bug you are referring to.

I thought it was pretty clear from me commenting 2 minutes after the bug was mentioned. Sorry! But see if that fixes your problem, would then mean these two are properly related and a fix might be easier to find.

wpostma · 4 months ago

This is driving me insane and is still happening in March 2026. Claude itself says:

The bug: the Write tool on Windows always produces CRLF line endings with no option to control this, making it
impossible to correctly create .sh or .py files without a post-write fixup step.

I can't use claude on windows because it's too windows. That's so meta.

Windows all the time with no workaround for those of us who use WSL with claude. The claude that runs inside wsl has this fault also.

Windows users use claude to ssh into linux machines also. This is unacceptable. We need a top level rule that is respected that says "writing a windows file uses CRLF", "writing a bash script never uses CRLF, ever".

Even claude itself trips overitself with its use of gitbash (mingw) bash shells on Windows, when there's no wsl, and no ssl, and no orchestration across the cloud involved.

oxidworks · 3 months ago

Still happening on Ubuntu 24.04 / Linux 6.17 (April 2026). Concrete impact: deploy.sh created via Write tool breaks immediately with set: pipefail\r: invalid option because of CRLF. Requires sed -i 's/\r//' after every Write/Edit call on .sh files. The TERM workaround from #33910 did not help here (running inside VSCode extension).

wpostma · 3 months ago
Still happening on Ubuntu 24.04 / Linux 6.17 (April 2026). Concrete impact: deploy.sh created via Write tool breaks immediately with set: pipefail\r: invalid option because of CRLF. Requires sed -i 's/\r//' after every Write/Edit call on .sh files. The TERM workaround from #33910 did not help here (running inside VSCode extension).

Try piekstra's workaround in THIS thread from Feb 17.
https://github.com/anthropics/claude-code/issues/2805#issuecomment-3918792817

It really IS a bug in the write-tool, in claude code, and Anthropic really should fix it. It's embarassing that they're trying to scare us with AI taking over the world when it can't yet do CR/LF sequences versus LF sequences.

charl3y15 · 2 months ago

Happening to me every single time that it writes a script that's then copied via ssh to a remote Ubuntu computer

wpostma · 2 months ago

I have asked claude to analyze its own behaviour and here's what it says:

The Write Tool's Line-Ending Problem: Root Cause & Solution

The Core Issue

The Write tool currently operates under the principle: "preserve exactly what the model sends." (FileWriteTool)

This design was a deliberate choice to avoid a different corruption: the tool previously tried to preserve the original file's line endings, which caused "silent corruption" when bash scripts inherited CRLF from a CRLF file.

But the fix created a new bug: The model doesn't know what line endings the file should use. It guesses (often wrong on Linux), and the user gets CRLF when they need LF.

---

Why This Is a Real Bug, Not a Configuration Problem

It cannot be fixed with CLAUDE.md or hooks because:

  1. CLAUDE.md instructions are ignored by the model
  • The model doesn't read CLAUDE.md — it's system prompt context, not directly visible during code generation
  • User reports confirm: they added explicit instructions, the bug persists
  • The model fundamentally cannot know "use LF for .sh files on Linux" during generation
  1. Hooks can't fix the Write tool itself
  • Hooks fire after the Write tool completes (PostToolUse)
  • By then, the file is already written with CRLF
  • A hook could convert back to LF, but that's a workaround, not a fix
  • The harness should not require post-processing to fix data corruption
  1. The problem is upstream — in the Write tool's input, not output
  • The Write tool receives content with wrong line endings
  • A hook can't change what the model already sent
  • The Write tool must decide line endings before writing, not after

---

The Correct Fix: Line-Ending Awareness

The Write tool should be aware of the file's existing context before modifying it.

  1. Get the file's CURRENT line-ending convention from readFileState
  2. If file is version-controlled, also check the committed version
  3. Determine target line ending using a priority:
  4. Normalize model's content to the determined line ending BEFORE writing
  5. Write with awareness, not blind preservation

---

Why This Matters Even for Unix/Linux Users

Changing a file's line endings is destructive and invisible:

  1. Diff pollution — Every line appears changed in git diff (can hide real changes)
  2. Git blame corruption — Blame output becomes useless (blame shows the CRLF-conversion commit, not the real author)
  3. Merge conflicts — Simple merges fail because one branch has LF, another CRLF
  4. Execution failure — Shebangs fail: #!/bin/bash\r\n is not recognized on Linux
  5. Data integrity — The file's structure is silently corrupted without the user's consent

A user shouldn't have to run dos2unix or git add --renormalize to fix files that Claude Code should have written correctly in the first place.

---

Why readFileState Is the Key

The fix requires the Write tool to consult readFileState (which tracks what the harness last read) and git history:

  • readFileState holds the original file's line endings (captured when FileReadTool read it)
  • Git holds the authoritative committed version
  • Together, they answer: "What line endings does this file use in its reference state?"

The model sends line endings based on its training data (often CRLF-biased). The Write tool must override those with the file's actual convention.

---

Summary

The previous approach (preserving old line endings) failed because it couldn't distinguish legitimate CRLF from corrupted CRLF. The new approach solves this by checking git history — git is the source of truth.

fsc-eriker · 1 month ago

Adding a noise comment to prevent this from being closed.

ygoe · 1 month ago

That's interesting. I searched here and found lots of bugs about line endings. I always get LF line endings on Windows, despite all existing files use CR-LF. So Claude Code is definitely not looking at existing files. Now that I see it apparently writes CR-LF on Linux, maybe there's just a condition in the code flipped so everybody gets exactly the wrong thing?

I added this topic in my AGENTS.md file and it causes a lot of action using tools and running several commands of all kinds to handle this, so that's not an efficient solution. Now I'm testing a batch script that fixes files, and instruct Claude to run this at the end as part of usual verification (like build and run tests).

fsc-eriker · 1 month ago

Adding a noise comment to prevent this from being closed.

wpostma · 1 month ago

The line ending situation in June 2026 is still "awful mess", not just on Windows but also on Linux.
No change.

fsc-eriker · 10 days ago

Adding a noise comment to prevent this from being closed.

ondrejtucny · 8 days ago

This is becoming insanely obscene:

<img width="1375" height="111" alt="Image" src="https://github.com/user-attachments/assets/d64267c8-583d-4f46-b9c8-2284e424f9ac" />

Dear Anthropic, what's so complicated on fixing this BUG in the Write tool, so that it (a) respects the host operating system's convention and (b) interprets e.g. .editorconfig, VS Code's settings.json etc., and produces correct CR LF or LF line endings?

ygoe · 7 days ago
what's so complicated

Nobody's here. Anthropic isn't reading this. The application is unmaintained. There is no support at all. That's what makes it complicated.

I've written a script to normalise line endings in all files. I've mentioned it in AGENTS.md and explained how and when to call it. At first this was still observed but meanwhile Claude is mostly ignoring it. They rely on AI in general to find a solution, but the problem is that it's completely unreliable for routine work. AI, by design, finds a new creative way to solve a problem each time. And I've seen many different commands to fix line endings. Some of them failed, then it found a different way, and most of the time, it was eventually effective.

Bottom line: AI is completely unsuitable for routine work that has to be done reliably, consistently and the same way every time. Just create a script and remember to call it yourself.

I guess the product "Claude Code" was originally supposed to fill this gap of AI, but they don't care. Claude also prefers to use random commands it found online to read and find files, instead of the builtin tools. And then it constantly stumbles over Bash vs. PowerShell confusions. It's so embarrassing.

wpostma-ideal · 7 days ago

The line ending situation in mid JULY 2026 is still "awful mess", not just on Windows but also on Linux.
No change.

Everyone out here saying Fable 5 this and that, but we can't even write a Carriage Return, and/or Linefeed consistently.