{"record":{"id":"1380dfa273584847","repo":"agalwood/Motrix","slug":"invalid-firefox-extension-id-id","errorCode":null,"errorMessage":"invalid Firefox extension ID: ${id}","messagePattern":"invalid Firefox extension ID: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/core/bridge/trusted-extension-registry.ts","lineNumber":28,"sourceCode":"  addedAt: number\n}\n\nexport interface RegistryStore {\n  read(): Promise<string | null>\n  write(content: string): Promise<void>\n}\n\nconst CHROME_ID_RE = /^[a-p]{32}$/\nconst FIREFOX_ID_RE = /^([^@\\s]+@[^@\\s]+|\\{[0-9a-fA-F-]{36}\\})$/\n\nfunction validateId(id: string, browser: Browser): void {\n  if (browser === 'chromium') {\n    if (!CHROME_ID_RE.test(id)) {\n      throw new Error(`invalid Chrome extension ID: ${id}`)\n    }\n  } else {\n    if (!FIREFOX_ID_RE.test(id)) {\n      throw new Error(`invalid Firefox extension ID: ${id}`)\n    }\n  }\n}\n\nexport class TrustedExtensionRegistry {\n  private entries = new Map<string, TrustedExtension>()\n  private builtinIds = new Set<string>()\n\n  constructor(\n    private store: RegistryStore,\n    private builtin: Array<{ id: string; browser: Browser }>\n  ) {}\n\n  async load(): Promise<void> {\n    this.entries.clear()\n    this.builtinIds.clear()\n    for (const b of this.builtin) {\n      const e: TrustedExtension = {","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/agalwood/Motrix/blob/1a708ee57746c434e2c67a44bbf0906a976afea4/src/core/bridge/trusted-extension-registry.ts#L10-L46","documentation":"Thrown by validateId() inside TrustedExtensionRegistry when a Firefox extension ID fails the regex /^([^@\\s]+@[^@\\s]+|\\{[0-9a-fA-F-]{36}\\})$/ — it must be either an email-style ID (name@domain) or a brace-wrapped UUID ({xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}). Plain Error with no code. Reached via registry.add() for user entries.","triggerScenarios":"TrustedExtensionRegistry.add(id, 'firefox', source) is called with an id that is neither an email-style format nor a braced UUID — e.g. a plain string like 'my-extension', a UUID without braces, or a Chrome-style 32-char ID.","commonSituations":"User enters a Firefox extension name instead of its ID; copies a UUID without the enclosing braces; passes a Chrome extension ID (32 chars a-p) with browser 'firefox'; types a slug or shortname instead of the add-on's manifest ID.","solutions":["Find the Firefox extension ID in about:addons or the manifest.json 'browser_specific_settings.gecko.id' field","Ensure UUIDs are wrapped in braces: {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}","If the ID is a Chrome-style 32-char string, pass browser: 'chromium' instead","Validate against the FIREFOX_ID_RE before calling add()"],"exampleFix":"// before\nawait registry.add('my-cool-extension', 'firefox', 'user-added')\n// after\nawait registry.add('cool-extension@example.com', 'firefox', 'user-added')","handlingStrategy":"validation","validationCode":"const FIREFOX_ID_RE = /^([^@\\s]+@[^@\\s]+|\\{[0-9a-fA-F-]{36}\\})$/\nfunction isValidFirefoxId(id: string): boolean {\n  return FIREFOX_ID_RE.test(id)\n}\n// Before add:\nif (!isValidFirefoxId(id)) {\n  throw new Error(`Invalid Firefox extension ID (need name@domain or {uuid}): ${id}`)\n}","typeGuard":"function isFirefoxExtensionId(id: string): boolean {\n  return /^([^@\\s]+@[^@\\s]+|\\{[0-9a-fA-F-]{36}\\})$/.test(id)\n}","tryCatchPattern":"try {\n  await registry.add(id, 'firefox', 'user-added', label)\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('invalid Firefox extension ID')) {\n    showUserError('Enter a valid Firefox extension ID (name@domain or {uuid})')\n  } else throw e\n}","preventionTips":["Find Firefox extension IDs in about:addons or the manifest's browser_specific_settings.gecko.id","Ensure UUIDs are wrapped in braces","Do not confuse Chrome IDs (32 chars a-p) with Firefox IDs"],"tags":["validation","extension","firefox","registry","regex"],"backgroundTag":null,"analyzedSha":"1a708ee57746c434e2c67a44bbf0906a976afea4","analyzedAt":"2026-08-12T16:18:09.346Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}