Skip to content

Decode UTF-16 .env files on variable import - #3186

Closed
levivannoort wants to merge 1 commit into
mainfrom
fix/env-import-utf16
Closed

Decode UTF-16 .env files on variable import#3186
levivannoort wants to merge 1 commit into
mainfrom
fix/env-import-utf16

Conversation

@levivannoort

@levivannoort levivannoort commented Aug 26, 2026

Copy link
Copy Markdown
Member

What does this PR do?

File.text() always decodes UTF-8, but .env files written on Windows are often UTF-16 -- PowerShell's > redirect defaults to it. Decoded as UTF-8, every character gains an interleaved NUL byte, so importing such a file stored keys with a NUL after every letter -- an invalid environment variable name that invalidated the Kubernetes build job manifest and failed every subsequent deployment for that resource (this is the origin of a production incident on cloud).

This adds readEnvFile() to $lib/helpers/envfile: it detects UTF-16 by BOM (FF FE / FE FF), or by the interleaved-NUL byte pattern when the BOM is missing, and decodes with the right TextDecoder. Both import modals (importVariablesModal, uploadVariablesModal) now use it instead of File.text() -- so a PowerShell-authored .env simply imports correctly instead of erroring on every key.

Test plan

src/lib/helpers/envfile.test.ts -- 7 cases: UTF-8 (with/without BOM), UTF-16LE/BE (with/without BOM), and UTF-8 containing a genuine stray NUL staying UTF-8. All passing; lint clean.

Related PRs and Issues

File.text() always decodes UTF-8, but .env files written on Windows are
often UTF-16 (PowerShell's > redirect defaults to it). Decoded as UTF-8,
every character gains an interleaved NUL byte, so a key like
VITE_GEMINI_API_KEY was stored as V\u0000I\u0000T\u0000E... - an invalid
env var name that broke every subsequent deployment for the resource.

readEnvFile() detects UTF-16 by BOM, or by the interleaved-NUL pattern
when the BOM is missing, and decodes accordingly; both import modals now
use it instead of File.text().
@appwrite

appwrite Bot commented Aug 26, 2026

Copy link
Copy Markdown

Console (appwrite/console)

Project ID: 688b7bf400350cbd60e9

Sites (1)
Site Status Logs Preview QR
console-stage
688b7cf6003b1842c9dc
Ready Ready View Logs Preview URL QR Code

Tip

Deploy functions via zip upload or connect directly to your Git repo

@greptile-apps

greptile-apps Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds encoding-aware .env file reading and routes both variable-import modals through it, with tests for UTF-8 and UTF-16 variants. The BOM paths are deterministic, but the BOM-less heuristic still rejects valid UTF-16 files whose contents are predominantly non-ASCII.

  • Adds BOM and interleaved-NUL detection for UTF-16LE and UTF-16BE.
  • Uses the new reader in both variable-import workflows.
  • Adds unit coverage for UTF-8, UTF-16, BOM-less files, and a stray UTF-8 NUL.

Confidence Score: 4/5

The PR should not merge until BOM-less UTF-16 files with predominantly non-ASCII values are decoded reliably rather than rejected during import.

The new detector only recognizes BOM-less UTF-16 when over 70% of all code units exhibit ASCII-style parity NULs, leaving a realistic class of valid Unicode-valued files on the original broken UTF-8 decoding path.

Files Needing Attention: src/lib/helpers/envfile.ts, src/lib/helpers/envfile.test.ts

Important Files Changed

Filename Overview
src/lib/helpers/envfile.ts Adds encoding detection and decoding, but the whole-file 70% NUL threshold misses BOM-less UTF-16 containing predominantly non-ASCII values.
src/lib/helpers/envfile.test.ts Adds broad encoding coverage, though all UTF-16 fixtures use ASCII-only content and therefore do not exercise the heuristic鈥檚 non-ASCII limitation.
src/lib/components/variables/importVariablesModal.svelte Correctly adopts the shared reader before the existing parser and validation flow.
src/routes/(console)/project-[region]-[project]/uploadVariablesModal.svelte Correctly adopts the shared reader before the existing parser and validation flow.

Comments Outside Diff (1)

  1. src/lib/helpers/envfile.ts, line 49-52 (link)

    P1 Non-ASCII UTF-16 misdetected

    When a BOM-less UTF-16 file contains an ASCII key followed by predominantly non-ASCII values, neither byte parity exceeds this whole-file 70% NUL threshold, so the helper decodes it as UTF-8. The resulting NUL-interleaved key fails variable validation, preventing the valid file from being imported.

    Fix in Claude Code Fix in Codex

Fix all with Greploop Fix All in Claude Code Fix All in Codex

Reviews (1): Last reviewed commit: "fix: decode UTF-16 .env files on variabl..." | Re-trigger Greptile

@levivannoort

Copy link
Copy Markdown
Member Author

Superseded by #3187 (same change with sanitized test fixtures).

@levivannoort
levivannoort deleted the fix/env-import-utf16 branch August 26, 2026 10:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant