{"record":{"id":"1c6b72edee38a1b5","repo":"philc/vimium","slug":"the-linkhintcharacters-setting-must-have-more-than","errorCode":null,"errorMessage":"The linkHintCharacters setting must have more than 1 character.","messagePattern":"The linkHintCharacters setting must have more than 1 character\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"content_scripts/link_hints.js","lineNumber":861,"sourceCode":"    if (this.hintMode != null) this.hintMode.exit();\n  }\n\n  removeHintMarkers() {\n    if (this.containerEl) {\n      DomUtils.removeElement(this.containerEl);\n    }\n    this.containerEl = null;\n  }\n}\n\n// Use characters for hints, and do not filter links by their text.\nclass AlphabetHints {\n  constructor() {\n    this.linkHintCharacters = Settings.get(\"linkHintCharacters\").toLowerCase();\n    // Ensure we have more than 1 character to generate hint strings. With 1 character, every hint\n    // will be another hint's prefix (\"1\", \"11\", ...).\n    if (this.linkHintCharacters.length <= 1) {\n      throw new Error(\"The linkHintCharacters setting must have more than 1 character.\");\n    }\n    this.hintKeystrokeQueue = [];\n  }\n\n  fillInMarkers(hintMarkers) {\n    const hintStrings = this.hintStrings(hintMarkers.length);\n    if (hintMarkers.length != hintStrings.length) {\n      // This can only happen if the user's linkHintCharacters setting is empty.\n      console.warn(\"Unable to generate link hint strings.\");\n    } else {\n      for (let i = 0; i < hintMarkers.length; i++) {\n        const marker = hintMarkers[i];\n        marker.hintString = hintStrings[i];\n        if (marker.isLocalMarker()) {\n          marker.element.innerHTML = spanWrap(marker.hintString.toUpperCase());\n        }\n      }\n    }","sourceCodeStart":843,"sourceCodeEnd":879,"githubUrl":"https://github.com/philc/vimium/blob/5aa29614bf1dce05e0d316f8c38722e17f9b38c3/content_scripts/link_hints.js#L843-L879","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Set linkHintCharacters in the extension options to a string of at least 2 unique characters (default is 'sadfjklewcmpgh').","If settings were imported or synced, restore/repair the linkHintCharacters value in the settings store.","In code/tests, guard before instantiating: only create AlphabetHints when Settings.get('linkHintCharacters').length > 1.","Wrap the constructor call in try/catch and fall back to the default character set if the stored setting is invalid."],"exampleFix":"// before\nSettings.set('linkHintCharacters', 'a');\nnew AlphabetHints(); // throws\n\n// after\nSettings.set('linkHintCharacters', 'sadfjklewcmpgh');\nnew AlphabetHints(); // ok","handlingStrategy":"validation","validationCode":"const chars = (Settings.get('linkHintCharacters') || '').toLowerCase();\nif (typeof chars !== 'string' || chars.length <= 1) {\n  throw new Error('linkHintCharacters must contain at least 2 characters');\n}","typeGuard":"function hasValidHintChars(value) {\n  return typeof value === 'string' && value.toLowerCase().length > 1;\n}","tryCatchPattern":"let hints;\ntry {\n  hints = new AlphabetHints();\n} catch (e) {\n  if (e.message.includes('linkHintCharacters')) {\n    Settings.set('linkHintCharacters', 'sadfjklewcmpgh');\n    hints = new AlphabetHints();\n  } else { throw e; }\n}","preventionTips":["Never persist linkHintCharacters shorter than 2 characters; validate on options-page save.","Validate settings after JSON import or sync before applying them.","Add a unit test asserting AlphabetHints construction with the shipped default settings.","Fall back to defaults when Settings.get returns empty/null values."],"tags":["configuration","validation","browser-extension"],"backgroundTag":"invalid-setting-value","analyzedSha":"5aa29614bf1dce05e0d316f8c38722e17f9b38c3","analyzedAt":"2026-08-30T03:46:46.119Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}