# Bad value “” for attribute “aria-labelledby” on element “a”: An IDREFS value must contain at least one non-whitespace character.

> Canonical HTML version: https://rocketvalidator.com/html-validation/bad-value-for-attribute-aria-labelledby-on-element-a-an-idrefs-value-must-contain-at-least-one-non-whitespace-character
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

The `aria-labelledby` attribute accepts an **IDREFS** value — a space-separated list of one or more `id` values that reference other elements in the document. The validator expects each ID in the list to be non-empty and contain at least one non-whitespace character. When the attribute is set to an empty string (`aria-labelledby=""`), it violates this constraint and triggers the validation error.

This issue commonly arises in templating systems and JavaScript frameworks where a variable intended to hold an ID reference resolves to an empty string. For example, a template like `aria-labelledby="{{ labelId }}"` will produce an empty attribute if `labelId` is undefined or blank.

### Why this matters

The `aria-labelledby` attribute is one of the highest-priority methods for computing an element's **accessible name**. According to the accessible name computation algorithm, `aria-labelledby` overrides all other naming sources — including visible text content, `aria-label`, and the `title` attribute. When `aria-labelledby` is present but empty or broken, screen readers may calculate the link's accessible name as empty, effectively making the link invisible or meaningless to assistive technology users. A link with no accessible name is a significant accessibility barrier: users cannot determine where the link goes or what it does.

Beyond accessibility, an empty `aria-labelledby` also signals invalid HTML according to both the WHATWG HTML living standard and the WAI-ARIA specification, which define the IDREFS type as requiring at least one valid token.

### How to fix it

You have several options depending on your situation:

1. **Reference a valid ID** — Point `aria-labelledby` to the `id` of an existing element whose text content should serve as the link's accessible name.
2. **Remove the attribute and use visible link text** — If the link already contains descriptive text, `aria-labelledby` is unnecessary.
3. **Use `aria-label` instead** — For icon-only links where no visible label element exists, `aria-label` provides a concise accessible name directly on the element.
4. **Conditionally render the attribute** — In templates, use conditional logic to omit `aria-labelledby` entirely when there's no valid ID to reference, rather than rendering an empty value.

## Examples

### Invalid: empty `aria-labelledby`

This triggers the validation error because the attribute value contains no non-whitespace characters.

```html
<a href="/report" aria-labelledby=""></a>
```

### Invalid: whitespace-only `aria-labelledby`

A value containing only spaces is equally invalid — IDREFS requires at least one actual token.

```html
<a href="/report" aria-labelledby="   "></a>
```

### Fixed: referencing an existing element by `id`

The `aria-labelledby` attribute points to a `<span>` whose text content becomes the link's accessible name.

```html
<a href="/report" aria-labelledby="report-link-text">
  <svg aria-hidden="true" viewBox="0 0 16 16"></svg>
</a>
<span id="report-link-text">View report</span>
```

### Fixed: referencing multiple IDs

You can concatenate text from multiple elements by listing their IDs separated by spaces. The accessible name is built by joining the referenced text in order.

```html
<span id="action">Learn more:</span>
<span id="subject">Apples</span>

<a href="/apples" aria-labelledby="action subject">
  <svg aria-hidden="true" viewBox="0 0 16 16"></svg>
</a>
```

In this case, the computed accessible name is "Learn more: Apples".

### Fixed: using visible link text instead

When the link already contains descriptive text, no ARIA attribute is needed. This is the simplest and most robust approach.

```html
<a href="/report">View report</a>
```

### Fixed: using `aria-label` for an icon-only link

When there is no separate visible label element to reference, `aria-label` provides the accessible name directly.

```html
<a href="/search" aria-label="Search">
  <svg aria-hidden="true" viewBox="0 0 16 16"></svg>
</a>
```

### Fixed: conditional rendering in a template

If you're using a templating engine, conditionally include the attribute only when a value exists. The exact syntax varies by framework, but here's the general idea:

```html
<!-- Instead of always rendering the attribute: -->
<!-- <a href="/report" aria-labelledby="{{ labelId }}"> -->

<!-- Only render it when labelId has a value: -->
<!-- <a href="/report" {{#if labelId}}aria-labelledby="{{labelId}}"{{/if}}> -->
```

This prevents the empty-attribute problem at its source rather than patching it after the fact.
