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

  1. 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).
  2. Run `oxlint --fix` — the rule's fixer deletes the 3 BOM bytes (Span 0..3).
  3. Strip via CLI: `sed -i '1s/^\xEF\xBB\xBF//' file.js`.
  4. 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

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


AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20). Data as JSON: /api/errors/7c409245410d98c6. Report an issue: GitHub.