From dfc5543b90d7da91f796d0e57b325e55917ebcd0 Mon Sep 17 00:00:00 2001 From: h1whelan Date: Mon, 30 Mar 2026 10:17:53 +0100 Subject: [PATCH] Fix: strip UTF-8 BOM from .env files to prevent silent first-variable loss When a .env file is saved with a UTF-8 BOM (common with JetBrains IDEs on Windows), the BOM character (\ufeff) was prepended to the first variable name, making it silently inaccessible via its intended key. Strip the BOM in Reader.__init__ so all variables are parsed correctly regardless of whether the file contains a BOM. Fixes #637 Co-Authored-By: Claude Opus 4.6 (1M context) --- src/dotenv/parser.py | 2 +- tests/test_parser.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/dotenv/parser.py b/src/dotenv/parser.py index eb100b47..66773604 100644 --- a/src/dotenv/parser.py +++ b/src/dotenv/parser.py @@ -68,7 +68,7 @@ class Error(Exception): class Reader: def __init__(self, stream: IO[str]) -> None: - self.string = stream.read() + self.string = stream.read().removeprefix("\ufeff") self.position = Position.start() self.mark = Position.start() diff --git a/tests/test_parser.py b/tests/test_parser.py index 43386e5a..4ec5a5af 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -545,6 +545,35 @@ ), ], ), + # UTF-8 BOM at the start of the file should be stripped + ( + "\ufeffa=b", + [ + Binding( + key="a", + value="b", + original=Original(string="a=b", line=1), + error=False, + ) + ], + ), + ( + "\ufeffa=b\nc=d", + [ + Binding( + key="a", + value="b", + original=Original(string="a=b\n", line=1), + error=False, + ), + Binding( + key="c", + value="d", + original=Original(string="c=d", line=2), + error=False, + ), + ], + ), ], ) def test_parse_stream(test_input, expected):