oxc-project/oxc · error · OxcDiagnostic

Missing `alt` attribute.

Error message

Missing `alt` attribute.

What it means

This is the oxlint `jsx-a11y/alt-text` diagnostic for `<img>` elements without alternative text. It fires when an `img` (or a component listed in the rule's `img` config) has no `alt` attribute at all, and no usable `aria-label`/`aria-labelledby` fallback. Alt text is what screen readers announce for images, so a missing `alt` makes the element inaccessible; decorative images should use `alt=""`.

Source

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

};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;
use oxc_str::CompactStr;
use schemars::JsonSchema;

use crate::{
    AstNode,
    context::LintContext,
    rule::Rule,
    utils::{
        get_element_type, get_prop_value, get_string_literal_prop_value, has_jsx_prop_ignore_case,
        object_has_accessible_child,
    },
};

fn missing_alt_prop(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Missing `alt` attribute.")
        .with_help("Must have `alt` prop, either with meaningful text, or an empty string for decorative images.")
        .with_label(span)
}

fn missing_alt_value(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Invalid `alt` value.")
        .with_help(
            "Must have meaningful value for `alt` prop. Use alt=\"\" for presentational images.",
        )
        .with_label(span)
}

fn aria_label_value(span: Span) -> OxcDiagnostic {
    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)
}

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Add meaningful alt text: `<img src="chart.png" alt="Q3 revenue by region" />`.
  2. For decorative images use an empty string: `<img src="spacer.gif" alt="" />`.
  3. If the attribute genuinely cannot be statically seen (spread props), move the spread so `alt` is explicit, or pass `alt` through your wrapper component.
  4. Register wrappers in the rule config: `"jsx-a11y/alt-text": ["error", { "img": ["Picture"] }]`.

Example fix

// before
<img src="/logo.svg" />
<Avatar user={u} />

// after
<img src="/logo.svg" alt="Acme logo" />
<Avatar user={u} alt={u.name} />
Defensive patterns

Strategy: validation

Validate before calling

// crude guard for wrappers: make alt required in props and forward it
// Avatar.tsx
type AvatarProps = { user: User; alt?: string };
export function Avatar({ user, alt }: AvatarProps) {
  return <img src={user.avatarUrl} alt={alt ?? user.name} />; // never renders alt-less
}

Prevention

When it happens

Trigger: `run` sees a JSX opening element resolving to `img` (default or via `elements`/`img` config) where `has_jsx_prop_ignore_case(node, "alt")` finds nothing, the element has no non-empty `aria-label`, and no non-empty `aria-labelledby`. Spread-props elements are typically skipped since the attribute cannot be proven absent.

Common situations: Component libraries wrapping `<img>` in custom `<Picture>`/`<Avatar>` components that forget to forward `alt`; decorative divider images; enabling the `jsx_a11y` plugin on a legacy codebase for the first time.

Related errors


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