{"record":{"id":"c391cb136e29837f","repo":"musistudio/claude-code-router","slug":"deep-link-failed-to-register-appdeeplinkprotoc","errorCode":null,"errorMessage":"[deep-link] Failed to register ${appDeepLinkProtocol} protocol: ${formatError(error)}","messagePattern":"\\[deep-link\\] Failed to register (.+?) protocol: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/electron/src/main/deep-link.ts","lineNumber":181,"sourceCode":"        dialog.showErrorBox(\"Failed to open CCR plugin app\", detail);\n      } catch {\n        // The console error above remains available when the dialog API is unavailable.\n      }\n      windowsManager.showMainWindow();\n    } finally {\n      this.openingPluginRequests.delete(requestKey);\n    }\n  }\n\n  private registerProtocolClient(): void {\n    try {\n      if (process.defaultApp && process.argv.length >= 2) {\n        app.setAsDefaultProtocolClient(appDeepLinkProtocol, process.execPath, [path.resolve(process.argv[1])]);\n        return;\n      }\n      app.setAsDefaultProtocolClient(appDeepLinkProtocol);\n    } catch (error) {\n      console.warn(`[deep-link] Failed to register ${appDeepLinkProtocol} protocol: ${formatError(error)}`);\n    }\n  }\n}\n\nasync function ensurePluginAppUrlAvailable(config: AppConfig, appUrl: string, startedGateway: boolean): Promise<void> {\n  try {\n    await waitForPluginAppUrl(\n      appUrl,\n      startedGateway ? pluginAppStartupProbeTimeoutMs : pluginAppExistingGatewayProbeTimeoutMs\n    );\n    return;\n  } catch (error) {\n    if (startedGateway) {\n      throw error;\n    }\n    console.warn(`[deep-link] Plugin app URL was not reachable on the running gateway; restarting gateway once. ${formatError(error)}`);\n  }\n","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/musistudio/claude-code-router/blob/99f24806c6a2c660b16e53e95211c517448a6c90/packages/electron/src/main/deep-link.ts#L163-L199","documentation":"Electron's app.setAsDefaultProtocolClient failed while registering the app's custom deep-link protocol. The call throws on some platforms when registry access (Windows) or LaunchServices registration (macOS) fails, and the wrapper logs it instead of crashing.","triggerScenarios":"Calling register() during app startup on Windows without admin rights, a sandboxed/dev environment where HKCU registry writes fail, or a protocol already claimed by another app. Also fires when process.defaultApp path handling passes a bad argv[1] in dev mode.","commonSituations":"Running unpackaged (electron .) where execPath/argv differ, corporate machines with registry policies, macOS during CI without a proper bundle id, or antivirus blocking registry writes.","solutions":["Run the app from a proper build/installer where process.defaultApp is false","Verify the protocol name is unique and not registered by another application","On Windows, check HKCU\\Software\\Classes\\<protocol> manually and delete stale entries","Wrap registration in a retry after app 'ready' if currently called before it"],"exampleFix":"// before\napp.setAsDefaultProtocolClient(appDeepLinkProtocol);\n// after\nif (app.isReady()) {\n  app.setAsDefaultProtocolClient(appDeepLinkProtocol);\n} else {\n  app.whenReady().then(() => app.setAsDefaultProtocolClient(appDeepLinkProtocol));\n}","handlingStrategy":"try-catch","validationCode":"if (!app.isReady()) { /* defer registration */ }","typeGuard":"const isProtocolName = (v: string): v is string => /^[a-z][a-z0-9+.-]*$/.test(v);","tryCatchPattern":"try { app.setAsDefaultProtocolClient(proto); } catch (e) { console.warn(`register failed: ${formatError(e)}`); }","preventionTips":["Register protocols only after app ready","Use a unique protocol scheme","Test in packaged builds, not just dev mode"],"tags":["electron","deep-link","protocol-registration","startup"],"backgroundTag":"protocol-handler-registration-failed","analyzedSha":"99f24806c6a2c660b16e53e95211c517448a6c90","analyzedAt":"2026-08-27T04:11:01.184Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}