oxc-project/oxc · error · OxcDiagnostic

Missing alternative text.

Error message

Missing alternative text.

What it means

This is the oxlint `jsx-a11y/alt-text` diagnostic for `<object>` embeds without a text alternative. Embedded `<object>` content (PDFs, plugins, media) is invisible to assistive technology unless the element exposes `alt`, `aria-label`, or `aria-labelledby`, so the rule requires one of the three.

Source

Thrown at crates/oxc_linter/src/rules/jsx_a11y/alt_text.rs:54

    OxcDiagnostic::warn("Missing value for `aria-label` attribute.")
        .with_help("Give `aria-label` a meaningful value. Prever the `alt` attribute over `aria-label` for images.")
        .with_label(span)
}

fn aria_labelled_by_value(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Missing value for `aria-labelledby` attribute.")
        .with_help("Give `aria-labelledby` an ID to a label element. Prefer the `alt` attribute over `aria-labelledby` for images.")
        .with_label(span)
}

fn prefer_alt(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("ARIA used where native HTML could suffice.")
        .with_help("Prefer alt=\"\" over presentational role. Native HTML attributes should be preferred for accessibility before resorting to ARIA attributes.")
        .with_label(span)
}

fn object(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Missing alternative text.")
        .with_help("Embedded <object> elements must have a text alternative through the `alt`, `aria-label`, or `aria-labelledby` prop.")
        .with_label(span)
}

fn area(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Missing alternative text.")
        .with_help("Each area of an image map must have a text alternative through the `alt`, `aria-label`, or `aria-labelledby` prop.")
        .with_label(span)
}

fn input_type_image(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Missing alternative text.")
        .with_help("<input> elements with type=\"image\" must have a text alternative through the `alt`, `aria-label`, or `aria-labelledby` prop.")
        .with_label(span)
}

#[derive(Debug, Default, Clone)]
pub struct AltText(Box<AltTextConfig>);

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Add `aria-label` (or `aria-labelledby` to visible text) describing the embed: `<object data="/report.pdf" aria-label="2024 annual report, PDF" />`.
  2. Add `title` plus a text fallback inside the object tag for broader support.
  3. Register custom wrappers in the rule config so they are checked too.

Example fix

// before
<object data="/report.pdf" type="application/pdf" />

// after
<object data="/report.pdf" type="application/pdf" aria-label="2024 annual report (PDF)">
  <p>Your browser cannot display PDFs. <a href="/report.pdf">Download the report</a>.</p>
</object>
Defensive patterns

Strategy: validation

Validate before calling

// Wrapper that forces an accessible name on object embeds
type PdfEmbedProps = { src: string; label: string };
export function PdfEmbed({ src, label }: PdfEmbedProps) {
  return <object data={src} type="application/pdf" aria-label={label} />;
}

Prevention

When it happens

Trigger: A JSX opening element resolves to `object` (default element set or via the rule's `object` config list) and has none of `alt`, `aria-label`, `aria-labelledby` with a usable value.

Common situations: PDF viewer embeds, legacy plugin embeds, and data visualizations rendered through `<object>`; wrapper components (`<PdfEmbed>`) that don't forward an accessible name.

Related errors


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