diff --git a/pyupgrade.py b/pyupgrade.py
index dab7eb2..bcd4250 100644
--- a/pyupgrade.py
+++ b/pyupgrade.py
@@ -1058,6 +1058,10 @@ def _fix_percent_format(contents_text: str) -> str:
         if node is None:
             continue
 
+        # TODO: handle \N escape sequences
+        if r'\N' in token.src:
+            continue
+
         if isinstance(node.right, ast.Tuple):
             _fix_percent_format_tuple(tokens, i, node)
         elif isinstance(node.right, ast.Dict):
@@ -2255,6 +2259,10 @@ def _fix_fstrings(contents_text: str) -> str:
         if node is None:
             continue
 
+        # TODO: handle \N escape sequences
+        if r'\N' in token.src:
+            continue
+
         paren = i + 3
         if tokens_to_src(tokens[i + 1:paren + 1]) != '.format(':
             continue

Valid f-string conversion throws KeyError
While working on a conversion project, I noticed that certain files would throw `KeyError`'s for `\N{...}` strings.

A minimal test case looks like:
```python
world = "world"
print("hello {} \N{snowman}".format(world))
```

Which I would expect to be left alone or rewritten as:
```python
world = "world"
print(f"hello {world} \N{snowman}")
```

I had trouble reproducing it in pytests. This seemed to trigger the same error:
```diff
diff --git tests/fstrings_test.py tests/fstrings_test.py
index d850293..a772a0f 100644
--- tests/fstrings_test.py
+++ tests/fstrings_test.py
@@ -48,6 +48,7 @@ def test_fix_fstrings_noop(s):
         ('"hello {}!".format(name)', 'f"hello {name}!"'),
         ('"{}{{}}{}".format(escaped, y)', 'f"{escaped}{{}}{y}"'),
         ('"{}{b}{}".format(a, c, b=b)', 'f"{a}{b}{c}"'),
+        (r'"{}\N{snowman}".format(a)', r'f"{a}\N{snowman}"'),
         # TODO: poor man's f-strings?
         # '"{foo}".format(**locals())'
     ),
```
diff --git a/tests/format_literals_test.py b/tests/format_literals_test.py
index ae656d1..f3610a1 100644
--- a/tests/format_literals_test.py
+++ b/tests/format_literals_test.py
@@ -49,6 +49,8 @@ def test_intentionally_not_round_trip(s, expected):
         "'{' '0}'.format(1)",
         # comment looks like placeholder but is not!
         '("{0}" # {1}\n"{2}").format(1, 2, 3)',
+        # TODO: this works by accident (extended escape treated as placeholder)
+        r'"\N{snowman} {}".format(1)',
     ),
 )
 def test_format_literals_noop(s):
diff --git a/tests/fstrings_test.py b/tests/fstrings_test.py
index d850293..2090930 100644
--- a/tests/fstrings_test.py
+++ b/tests/fstrings_test.py
@@ -26,6 +26,8 @@ from pyupgrade import _fix_fstrings
         '"{:{}}".format(x, y)',
         '"{a[b]}".format(a=a)',
         '"{a.a[b]}".format(a=a)',
+        # TODO: handle \N escape sequences
+        r'"\N{snowman} {}".format(a)',
         # not enough placeholders / placeholders missing
         '"{}{}".format(a)', '"{a}{b}".format(a=a)',
     ),
diff --git a/tests/percent_format_test.py b/tests/percent_format_test.py
index 6301620..e1c5f8d 100644
--- a/tests/percent_format_test.py
+++ b/tests/percent_format_test.py
@@ -176,6 +176,8 @@ def test_simplify_conversion_flag(s, expected):
         '"%(and)s" % {"and": 2}',
         # invalid string formats
         '"%" % {}', '"%(hi)" % {}', '"%2" % {}',
+        # TODO: handle \N escape sequences
+        r'"%s \N{snowman}" % (a,)',
     ),
 )
 def test_percent_format_noop(s):

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest
3.9
requirements-dev.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
cfgv==3.4.0
covdefaults==2.3.0
coverage==7.8.0
distlib==0.3.9
exceptiongroup==1.2.2
filelock==3.18.0
identify==2.6.9
iniconfig==2.1.0
nodeenv==1.9.1
packaging==24.2
platformdirs==4.3.7
pluggy==1.5.0
pre_commit==4.2.0
pytest==8.3.5
-e git+https://github.com/asottile/pyupgrade.git@e41b9c75f0cb73ce01d90bbfcb6bea558c42ff5d#egg=pyupgrade
PyYAML==6.0.2
tokenize_rt==6.1.0
tomli==2.2.1
virtualenv==20.29.3

name: pyupgrade
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - cfgv==3.4.0
      - covdefaults==2.3.0
      - coverage==7.8.0
      - distlib==0.3.9
      - exceptiongroup==1.2.2
      - filelock==3.18.0
      - identify==2.6.9
      - iniconfig==2.1.0
      - nodeenv==1.9.1
      - packaging==24.2
      - platformdirs==4.3.7
      - pluggy==1.5.0
      - pre-commit==4.2.0
      - pytest==8.3.5
      - pyyaml==6.0.2
      - tokenize-rt==6.1.0
      - tomli==2.2.1
      - virtualenv==20.29.3
prefix: /opt/conda/envs/pyupgrade

tests/fstrings_test.py::test_fix_fstrings_noop["\\N{snowman} tests/percent_format_test.py::test_percent_format_noop["%s
tests/format_literals_test.py::test_roundtrip_text[] tests/format_literals_test.py::test_roundtrip_text[foo] tests/format_literals_test.py::test_roundtrip_text[{}] tests/format_literals_test.py::test_roundtrip_text[{0}] tests/format_literals_test.py::test_roundtrip_text[{named}] tests/format_literals_test.py::test_roundtrip_text[{!r}] tests/format_literals_test.py::test_roundtrip_text[{:>5}] tests/format_literals_test.py::test_roundtrip_text[{{] tests/format_literals_test.py::test_roundtrip_text[}}] tests/format_literals_test.py::test_roundtrip_text[{0!s:15}] tests/format_literals_test.py::test_intentionally_not_round_trip[{:}-{}] tests/format_literals_test.py::test_intentionally_not_round_trip[{0:}-{0}] tests/format_literals_test.py::test_intentionally_not_round_trip[{0!r:}-{0!r}] tests/format_literals_test.py::test_format_literals_noop["{0}"format(1)] tests/format_literals_test.py::test_format_literals_noop['{}'.format(1)] tests/format_literals_test.py::test_format_literals_noop['{'.format(1)] tests/format_literals_test.py::test_format_literals_noop['}'.format(1)] tests/format_literals_test.py::test_format_literals_noop[x tests/format_literals_test.py::test_format_literals_noop['{0} tests/format_literals_test.py::test_format_literals_noop['{0:<{1}}'.format(1, tests/format_literals_test.py::test_format_literals_noop['{' tests/format_literals_test.py::test_format_literals_noop[("{0}" tests/format_literals_test.py::test_format_literals_noop["\\N{snowman} tests/format_literals_test.py::test_format_literals['{0}'.format(1)-'{}'.format(1)] tests/format_literals_test.py::test_format_literals['{0:x}'.format(30)-'{:x}'.format(30)] tests/format_literals_test.py::test_format_literals[x tests/format_literals_test.py::test_format_literals['''{0}\n{1}\n'''.format(1, tests/format_literals_test.py::test_format_literals['{0}' tests/format_literals_test.py::test_format_literals[print(\n tests/format_literals_test.py::test_format_literals[("{0}").format(1)-("{}").format(1)] tests/fstrings_test.py::test_fix_fstrings_noop[(] tests/fstrings_test.py::test_fix_fstrings_noop['{'.format(a)] tests/fstrings_test.py::test_fix_fstrings_noop['}'.format(a)] tests/fstrings_test.py::test_fix_fstrings_noop["{}" tests/fstrings_test.py::test_fix_fstrings_noop["{}".format(\n tests/fstrings_test.py::test_fix_fstrings_noop["{} tests/fstrings_test.py::test_fix_fstrings_noop["{foo} tests/fstrings_test.py::test_fix_fstrings_noop["{0} tests/fstrings_test.py::test_fix_fstrings_noop["{x} tests/fstrings_test.py::test_fix_fstrings_noop["{x.y} tests/fstrings_test.py::test_fix_fstrings_noop[b"{} tests/fstrings_test.py::test_fix_fstrings_noop["{:{}}".format(x, tests/fstrings_test.py::test_fix_fstrings_noop["{a[b]}".format(a=a)] tests/fstrings_test.py::test_fix_fstrings_noop["{a.a[b]}".format(a=a)] tests/fstrings_test.py::test_fix_fstrings_noop["{}{}".format(a)] tests/fstrings_test.py::test_fix_fstrings_noop["{a}{b}".format(a=a)] tests/fstrings_test.py::test_fix_fstrings["{} tests/fstrings_test.py::test_fix_fstrings["{1} tests/fstrings_test.py::test_fix_fstrings["{x.y}".format(x=z)-f"{z.y}"] tests/fstrings_test.py::test_fix_fstrings["{.x} tests/fstrings_test.py::test_fix_fstrings["{}".format(a())-f"{a()}"] tests/fstrings_test.py::test_fix_fstrings["{}".format(a.b())-f"{a.b()}"] tests/fstrings_test.py::test_fix_fstrings["{}".format(a.b().c())-f"{a.b().c()}"] tests/fstrings_test.py::test_fix_fstrings["hello tests/fstrings_test.py::test_fix_fstrings["{}{{}}{}".format(escaped, tests/fstrings_test.py::test_fix_fstrings["{}{b}{}".format(a, tests/percent_format_test.py::test_parse_percent_format[""-expected0] tests/percent_format_test.py::test_parse_percent_format["%%"-expected1] tests/percent_format_test.py::test_parse_percent_format["%s"-expected2] tests/percent_format_test.py::test_parse_percent_format["%s tests/percent_format_test.py::test_parse_percent_format["%(hi)s"-expected4] tests/percent_format_test.py::test_parse_percent_format["%()s"-expected5] tests/percent_format_test.py::test_parse_percent_format["%#o"-expected6] tests/percent_format_test.py::test_parse_percent_format["% tests/percent_format_test.py::test_parse_percent_format["%5d"-expected8] tests/percent_format_test.py::test_parse_percent_format["%*d"-expected9] tests/percent_format_test.py::test_parse_percent_format["%.f"-expected10] tests/percent_format_test.py::test_parse_percent_format["%.5f"-expected11] tests/percent_format_test.py::test_parse_percent_format["%.*f"-expected12] tests/percent_format_test.py::test_parse_percent_format["%ld"-expected13] tests/percent_format_test.py::test_parse_percent_format["%(complete)#4.4f"-expected14] tests/percent_format_test.py::test_percent_to_format[%s-{}] tests/percent_format_test.py::test_percent_to_format[%%%s-%{}] tests/percent_format_test.py::test_percent_to_format[%(foo)s-{foo}] tests/percent_format_test.py::test_percent_to_format[%2f-{:2f}] tests/percent_format_test.py::test_percent_to_format[%r-{!r}] tests/percent_format_test.py::test_percent_to_format[%a-{!a}] tests/percent_format_test.py::test_simplify_conversion_flag[-] tests/percent_format_test.py::test_simplify_conversion_flag[ tests/percent_format_test.py::test_simplify_conversion_flag[#0- tests/percent_format_test.py::test_simplify_conversion_flag[--<] tests/percent_format_test.py::test_percent_format_noop["%s" tests/percent_format_test.py::test_percent_format_noop[b"%s" tests/percent_format_test.py::test_percent_format_noop["%*s" tests/percent_format_test.py::test_percent_format_noop["%.*s" tests/percent_format_test.py::test_percent_format_noop["%d" tests/percent_format_test.py::test_percent_format_noop["%i" tests/percent_format_test.py::test_percent_format_noop["%u" tests/percent_format_test.py::test_percent_format_noop["%c" tests/percent_format_test.py::test_percent_format_noop["%#o" tests/percent_format_test.py::test_percent_format_noop["%()s" tests/percent_format_test.py::test_percent_format_noop["%4%" tests/percent_format_test.py::test_percent_format_noop["%.2r" tests/percent_format_test.py::test_percent_format_noop["%.2a" tests/percent_format_test.py::test_percent_format_noop[i tests/percent_format_test.py::test_percent_format_noop["%(1)s" tests/percent_format_test.py::test_percent_format_noop["%(a)s" tests/percent_format_test.py::test_percent_format_noop["%(ab)s" tests/percent_format_test.py::test_percent_format_noop["%(and)s" tests/percent_format_test.py::test_percent_format_noop["%" tests/percent_format_test.py::test_percent_format_noop["%(hi)" tests/percent_format_test.py::test_percent_format_noop["%2" tests/percent_format_test.py::test_percent_format["trivial" tests/percent_format_test.py::test_percent_format["%s" tests/percent_format_test.py::test_percent_format["%s%% tests/percent_format_test.py::test_percent_format["%3f" tests/percent_format_test.py::test_percent_format["%-5s" tests/percent_format_test.py::test_percent_format["%9s" tests/percent_format_test.py::test_percent_format["brace tests/percent_format_test.py::test_percent_format["%(k)s" tests/percent_format_test.py::test_percent_format["%(to_list)s"
pyupgrade.py
pyupgrade.py