philc/vimium · error · Error

The linkHintCharacters setting must have more than 1 charact

Error message

The linkHintCharacters setting must have more than 1 character.

What it means

AlphabetHints generates alphabetic link-hint strings from the user's linkHintCharacters setting. If the setting contains 1 or fewer characters, every generated hint string would be a prefix of another hint (e.g. 'a', 'aa', 'aaa'), making disambiguation impossible, so the constructor throws immediately. This is a fail-fast validation of user-supplied settings, not an internal bug.

Source

Thrown at content_scripts/link_hints.js:861

    if (this.hintMode != null) this.hintMode.exit();
  }

  removeHintMarkers() {
    if (this.containerEl) {
      DomUtils.removeElement(this.containerEl);
    }
    this.containerEl = null;
  }
}

// Use characters for hints, and do not filter links by their text.
class AlphabetHints {
  constructor() {
    this.linkHintCharacters = Settings.get("linkHintCharacters").toLowerCase();
    // Ensure we have more than 1 character to generate hint strings. With 1 character, every hint
    // will be another hint's prefix ("1", "11", ...).
    if (this.linkHintCharacters.length <= 1) {
      throw new Error("The linkHintCharacters setting must have more than 1 character.");
    }
    this.hintKeystrokeQueue = [];
  }

  fillInMarkers(hintMarkers) {
    const hintStrings = this.hintStrings(hintMarkers.length);
    if (hintMarkers.length != hintStrings.length) {
      // This can only happen if the user's linkHintCharacters setting is empty.
      console.warn("Unable to generate link hint strings.");
    } else {
      for (let i = 0; i < hintMarkers.length; i++) {
        const marker = hintMarkers[i];
        marker.hintString = hintStrings[i];
        if (marker.isLocalMarker()) {
          marker.element.innerHTML = spanWrap(marker.hintString.toUpperCase());
        }
      }
    }

View on GitHub (pinned to 5aa29614bf)

Solutions

  1. Set linkHintCharacters in the extension options to a string of at least 2 unique characters (default is 'sadfjklewcmpgh').
  2. If settings were imported or synced, restore/repair the linkHintCharacters value in the settings store.
  3. In code/tests, guard before instantiating: only create AlphabetHints when Settings.get('linkHintCharacters').length > 1.
  4. Wrap the constructor call in try/catch and fall back to the default character set if the stored setting is invalid.

Example fix

// before
Settings.set('linkHintCharacters', 'a');
new AlphabetHints(); // throws

// after
Settings.set('linkHintCharacters', 'sadfjklewcmpgh');
new AlphabetHints(); // ok
Defensive patterns

Strategy: validation

Validate before calling

const chars = (Settings.get('linkHintCharacters') || '').toLowerCase();
if (typeof chars !== 'string' || chars.length <= 1) {
  throw new Error('linkHintCharacters must contain at least 2 characters');
}

Type guard

function hasValidHintChars(value) {
  return typeof value === 'string' && value.toLowerCase().length > 1;
}

Try / catch

let hints;
try {
  hints = new AlphabetHints();
} catch (e) {
  if (e.message.includes('linkHintCharacters')) {
    Settings.set('linkHintCharacters', 'sadfjklewcmpgh');
    hints = new AlphabetHints();
  } else { throw e; }
}

Prevention

When it happens

Trigger: Constructing an AlphabetHints instance (created when link hints are activated in alphabet mode) while Settings.get('linkHintCharacters').toLowerCase() has length <= 1 — e.g. the setting is '', 'a', or a single character after lowercasing.

Common situations: Users (or options-sync code / imported settings files) set linkHintCharacters to a single character like 'asdf'.slice or an empty string; settings migration or JSON import wipes the default 'sadfjklewcmpgh'; tests instantiate AlphabetHints with a stubbed Settings returning a minimal value.

Related errors


AI-assisted analysis of philc/vimium@5aa29614bf (2026-08-30). Data as JSON: /api/errors/1c6b72edee38a1b5. Report an issue: GitHub.