oxc-project/oxc · warning · OxcDiagnostic
Unexpected Unicode BOM (Byte Order Mark)
Error message
Unexpected Unicode BOM (Byte Order Mark)
What it means
oxlint `eslint/unicode-bom` with the default `"never"` option: the source file begins with a UTF-8 BOM (U+FEFF, bytes EF BB BF). `unexpected_unicode_bom_diagnostic` (unicode_bom.rs:13) reports it; the run_once check (unicode_bom.rs:71-79) tests `source.starts_with('\u{feff}')` and offers a fix that deletes the first 3 bytes. UTF-8 does not need a BOM since byte order is irrelevant, so 'never' is the default per the rule docs.
Source
Thrown at crates/oxc_linter/src/rules/eslint/unicode_bom.rs:13
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{SPAN, Span};
use schemars::JsonSchema;
use serde::Deserialize;
use crate::{
context::LintContext,
rule::{DefaultRuleConfig, Rule},
};
fn unexpected_unicode_bom_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Unexpected Unicode BOM (Byte Order Mark)")
.with_help("File must not begin with the Unicode BOM")
.with_label(span)
}
fn expected_unicode_bom_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Expected Unicode BOM (Byte Order Mark)")
.with_help("File must begin with the Unicode BOM")
.with_label(span)
}
#[derive(Debug, Default, Clone, Deserialize)]
pub struct UnicodeBom(BomOptionType);
#[derive(Debug, Default, Clone, Deserialize, JsonSchema)]
#[serde(rename_all = "kebab-case")]
enum BomOptionType {
/// Always require a Unicode BOM (Byte Order Mark) at the beginning of the file.
Always,View on GitHub (pinned to e1e7af627c)
Solutions
- Re-save the file as UTF-8 without BOM (`:set nobomb` in vim; 'Save with encoding → UTF-8' in VS Code; `dos2unix` also strips it).
- Run `oxlint --fix` — the rule's fixer deletes the 3 BOM bytes (Span 0..3).
- Strip via CLI: `sed -i '1s/^\xEF\xBB\xBF//' file.js`.
- If your toolchain genuinely requires a BOM, configure `"unicode-bom": "always"` instead.
Example fix
// before (file bytes: EF BB BF) \uFEFFexport const a = 1; // after (plain UTF-8, no leading U+FEFF) export const a = 1;
Defensive patterns
Strategy: validation
Validate before calling
# fail if any source file starts with a UTF-8 BOM (EF BB BF) for f in $(git ls-files '*.js' '*.ts' '*.mjs' '*.cjs'); do head -c3 "$f" | od -An -tx1 | grep -q 'ef bb bf' && echo "BOM: $f" done
Prevention
- Configure your editor to save 'UTF-8 (no BOM)' and add a `.editorconfig` with `charset = utf-8`.
- Avoid PowerShell `Out-File`/`>` redirects for source files; they prepend a BOM by default in Windows PowerShell.
- Run `oxlint --fix` after Windows contributors' commits — the unicode-bom fixer strips the 3 bytes safely.
When it happens
Trigger: Any file whose first character is U+FEFF while the rule is configured `"never"` (or unconfigured, since Never is the default BomOptionType). Editors or PowerShell `Out-File` commonly prepend the BOM.
Common situations: Files saved on Windows with a BOM-producing editor; files piped through PowerShell redirects; concatenating files where a mid-stream BOM landed at the start; a CI lint step suddenly failing after a Windows contributor's commit.
Related errors
- Expected Unicode BOM (Byte Order Mark)
- Use the 'v' flag.
- Use the 'u' flag.
- Empty array binding pattern
- Empty object binding pattern
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/7c409245410d98c6.
Report an issue: GitHub.