{"record":{"id":"37a40f2e1773a7e4","repo":"Stirling-Tools/Stirling-PDF","slug":"this-tool-requires-an-account-sign-in-to-stirling","errorCode":null,"errorMessage":"This tool requires an account. Sign in to Stirling Cloud or connect to a self-hosted server to use it.","messagePattern":"This tool requires an account\\. Sign in to Stirling Cloud or connect to a self-hosted server to use it\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"frontend/editor/src/desktop/services/operationRouter.ts","lineNumber":165,"sourceCode":"    // Local-only mode: route everything to local backend; open settings if tool unavailable\n    if (mode === \"local\") {\n      if (operation && this.isToolEndpoint(operation)) {\n        const endpointName = this.extractEndpointName(operation);\n        const backendUrl = tauriBackendService.getBackendUrl();\n        if (backendUrl) {\n          const supportedLocally =\n            await endpointAvailabilityService.isEndpointSupportedLocally(\n              endpointName,\n              backendUrl,\n            );\n          if (!supportedLocally) {\n            // Open the connection settings so the user can sign in\n            window.dispatchEvent(\n              new CustomEvent(\"appConfig:navigate\", {\n                detail: { key: \"connectionMode\" },\n              }),\n            );\n            throw new Error(\n              i18n.t(\n                \"localMode.toolUnavailable\",\n                \"This tool requires an account. Sign in to Stirling Cloud or connect to a self-hosted server to use it.\",\n              ),\n            );\n          }\n        }\n      }\n      const backendUrl = tauriBackendService.getBackendUrl();\n      if (!backendUrl) {\n        throw new Error(\n          \"Backend URL not available - backend may still be starting\",\n        );\n      }\n      return backendUrl.replace(/\\/$/, \"\");\n    }\n\n    // Always route team endpoints to SaaS backend (existing logic)","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/Stirling-Tools/Stirling-PDF/blob/9ef20dcab80b85041912f045e17a6aea1d08f969/frontend/editor/src/desktop/services/operationRouter.ts#L147-L183","documentation":"Thrown by operationRouter.getBaseUrl in local-only mode when the requested tool endpoint is not supported by the bundled local backend (endpointAvailabilityService.isEndpointSupportedLocally returns false). The app first dispatches an appConfig:navigate event to open connection settings, then throws this localized 'toolUnavailable' message telling the user they must sign in to use the tool.","triggerScenarios":"User is in local-only mode (signed out / chose local) and triggers a tool the local backend cannot serve — e.g. a tool requiring a server-only feature, OCR model, or proprietary capability absent from the bundled backend.","commonSituations":"Local-only desktop user clicks a premium/server-only tool; the bundled backend lacks the endpoint or a heavy dependency (LibreOffice, OCR languages); the local backend is a stripped build.","solutions":["Sign in to Stirling Cloud or connect to a self-hosted server (the connection-settings panel was already opened for you) and retry the tool.","If self-hosting, ensure that server has the tool enabled and its dependencies installed.","For local use, install a backend build that includes the required capability.","Hide/disable tools the local backend cannot serve (consume endpointAvailabilityService in the UI)."],"exampleFix":"// before: tool button fires immediately\nonClick={() => runTool(endpoint)}\n\n// after: gate the button on local capability\nconst canRunLocal = mode !== 'local' || await endpointAvailabilityService.isEndpointSupportedLocally(name, backendUrl);\n<button disabled={!canRunLocal} onClick={() => runTool(endpoint)} />","handlingStrategy":"validation","validationCode":"const mode = await connectionModeService.getCurrentMode();\nconst canRunLocal = mode !== 'local'\n  || await endpointAvailabilityService.isEndpointSupportedLocally(endpointName, backendUrl);\nif (!canRunLocal) { /* hide/disable the tool, prompt sign-in */ return; }","typeGuard":"function isToolUnavailable(e: unknown): e is Error {\n  return e instanceof Error && /requires an account/.test(e.message);\n}","tryCatchPattern":"try { await runOperation(endpoint); }\ncatch (e) {\n  if (isToolUnavailable(e)) { /* connection settings already opened; prompt sign-in */ return; }\n  throw e;\n}","preventionTips":["Consume endpointAvailabilityService in the UI to disable unsupported tools in local mode.","Prompt sign-in before the user reaches an unsupported tool.","Keep the capability cache fresh after mode switches."],"tags":["local-mode","capability","endpoint-availability","routing","desktop"],"backgroundTag":null,"analyzedSha":"9ef20dcab80b85041912f045e17a6aea1d08f969","analyzedAt":"2026-08-13T22:11:39.827Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}