# Plan file encoding SSMS saves `.sqlplan` as UTF-16LE with a byte-order mark. `File.text()` assumes UTF-8, which turns such a plan into NUL-filled junk and makes the parser complain about the user's export. `lib/plan-file.ts` decodes by BOM first (UTF-32LE/BE, UTF-16LE/BE, UTF-8), then falls back to NUL density for BOM-less UTF-16: in ASCII XML roughly every other byte is `0x00`. The browser reads the dropped file into bytes and calls `decodePlan`; the server never sniffs encoding. That keeps [[ShowPlan digest]] independent of how the text arrived. Four encodings are pinned by tests: UTF-8, UTF-8 with BOM, UTF-16LE with BOM, UTF-16BE with BOM, and both UTF-16 variants with no BOM. A browser test uploads a generated UTF-16LE file and asserts the textarea holds no NUL characters. Related: [[ShowPlan digest]], [[Unit suites]], [[Playwright projects]].