# ruff W605: fix changes program behavior

Internal evidence sheet generated by fixhunt. Not an issue text. A human re-verifies, checks the duplicates
below, and writes the upstream report in their own words following the project's AI policy.

- Tool: ruff ruff 0.17.1
- Rule: W605 (tool labels the fix: unknown, this fix reported as safe)
- Oracle: fix-changes-behavior
- Judge (Nemotron 3 Ultra, advisory): intended-change, severity low. The rule rewrites the invalid escape sequence '\_' to the valid escaped backslash '\\_', which changes the string value from a newline followed by '_' to a newline followed by '\_'. This is exactly the semantic change the rule documents: eliminating the deprecated SyntaxWarning by making the escape sequence valid, even though the resulting string content differs.
- Program: minimized from 5 to 1 lines

## Reproducer

```python
s = '\n\_'
```

## Commands

```sh
python3 prog.py
ruff check --preview --isolated --select W605 --fix prog.py
python3 prog.py
```

## Observed

```
stderr before: /w/prog.py:1: SyntaxWarning: invalid escape sequence '\_'
stderr after: (none)
```

## Diff applied by the fix

```diff
--- orig.py	2026-10-22 13:32:14.454793666 -0400
+++ fixed.py	2026-10-22 13:32:16.915835012 -0400
@@ -1 +1 @@
-s = '\n\_'
+s = '\n\\_'
```

## Why the rewrite is not equivalent (model draft, verify before use)

The original string literal contains an invalid escape sequence `\_` which Python treats as two characters backslash and underscore while emitting a warning; replacing it with `\\_` yields a single escaped backslash followed by underscore changing the runtime value from `'\\_'` to `'\\\\_'`. This alters the string’s content so the program’s behavior differs.

## Upstream search

Queries: "W605 fix", "W605 invalid escape backslash underscore", "ruff W605 escape sequence warning fix", "invalid escape \_ to \\_ correction"

- related: https://github.com/astral-sh/ruff/issues/11491
  Existing report is about W605 fix in f-strings; new finding is a plain string literal.
- related: https://github.com/astral-sh/ruff/issues/8616
  Mentions W605 fixer creating unnecessary escapes; same rule but different context.
- duplicate: https://github.com/astral-sh/ruff/issues/11461
  Existing report 'W605 fix is unsafe' describes the same defect: the autofix changes '\_' to '\\_' in a plain string, altering runtime behavior.
- related: https://github.com/astral-sh/ruff/issues/10434
  W605 panic in f-strings; same rule but different trigger.
- related: https://github.com/astral-sh/ruff/issues/6987
  Autofix error involving W605; same rule but different construct.
- related: https://github.com/astral-sh/ruff/issues/5061
  Feature request to use raw strings for W605; same rule but not the same defect.
- related: https://github.com/astral-sh/ruff/issues/19543
  About W605 on byte strings; same rule but different string type.
- related: https://github.com/astral-sh/ruff/issues/5352
  PR for raw-string fix for W605; same rule but not the same defect.

<details><summary>All hits</summary>

- [github, open] Wrong fix for W605 in f-strings — https://github.com/astral-sh/ruff/issues/11491
- [github, open] Implement remaining `pycodestyle` rules — https://github.com/astral-sh/ruff/issues/2402
- [github, open] Include some of the checks from flake8-literal — https://github.com/astral-sh/ruff/issues/8616
- [github, closed] unused-function-argument not silenced by prefixed underscore if variable name is "次" — https://github.com/astral-sh/ruff/issues/28721
- [github, open] Implement Pylint — https://github.com/astral-sh/ruff/issues/970
- [github, closed] ISC002 makes W605 unfixable on playground — https://github.com/astral-sh/ruff/issues/19655
- [github, closed] W605 fix is unsafe — https://github.com/astral-sh/ruff/issues/11461
- [github, closed] Ruff does not clean up unused import if it has same name like object attribute — https://github.com/astral-sh/ruff/issues/12775
- [github, closed] Pack of fuzzer Autofix/Infinite loop errors [2] — https://github.com/astral-sh/ruff/issues/8402
- [github, closed] Rule W605 cause panic — https://github.com/astral-sh/ruff/issues/10434
- [tavily] Rules ANN401,W605 cause autofix error · Issue #6987 · astral-sh/ruff · GitHub — https://github.com/astral-sh/ruff/issues/6987
- [tavily] Change W605 autofix to use raw strings if possible · Issue #5061 · astral-sh/ruff · GitHub — https://github.com/astral-sh/ruff/issues/5061
- [tavily] Format breaks f-string with literal strings inside (versions 0.3.0 and 0.3.1) · Issue #10273 · astral-sh/ruff · GitHub — https://github.com/astral-sh/ruff/issues/10273
- [tavily] Should W605 flag certain byte string escapes? · Issue #19543 · astral-sh/ruff · GitHub — https://github.com/astral-sh/ruff/issues/19543
- [tavily] Change W605 autofix to use raw strings if possible by hauntsaninja · Pull Request #5352 · astral-sh/ruff · GitHub — https://github.com/astral-sh/ruff/pull/5352
- [tavily] Validation for ruff config file · Issue #10487 · astral-sh/ruff · GitHub — https://github.com/astral-sh/ruff/issues/10487
- [github, closed] In `ruff` 0.0.258 the `pydocstyle` rules are being enabled and can't be disabled with `[tool.ruff.pydocstyle]` defined.  — https://github.com/astral-sh/ruff/issues/3687
- [tavily] S608 - SQL Injection vector through string-based query ... — https://github.com/astral-sh/ruff/issues/18276

</details>
