{"record":{"id":"fe1002e9ff7dd535","repo":"Stirling-Tools/Stirling-PDF","slug":"connection-mode-is-locked-by-provisioning","errorCode":null,"errorMessage":"Connection mode is locked by provisioning","messagePattern":"Connection mode is locked by provisioning","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"frontend/editor/src/desktop/services/connectionModeService.ts","lineNumber":139,"sourceCode":"\n      this.currentConfig = config;\n      this.configLoadedOnce = true;\n    } catch (error) {\n      console.error(\"Failed to load connection config:\", error);\n      // Default to local mode on error — safer than showing SaaS UI for a\n      // desktop app whose bundled backend is always available.\n      this.currentConfig = {\n        mode: \"local\",\n        server_config: null,\n        lock_connection_mode: false,\n      };\n      this.configLoadedOnce = true;\n    }\n  }\n\n  async switchToSaaS(saasServerUrl: string): Promise<void> {\n    if (this.currentConfig?.lock_connection_mode) {\n      throw new Error(\"Connection mode is locked by provisioning\");\n    }\n\n    // Clear local-only flag and expiry-prompted flag when signing in\n    localStorage.removeItem(LOCAL_MODE_STORAGE_KEY);\n    localStorage.removeItem(JWT_EXPIRED_PROMPTED_KEY);\n\n    console.log(\"Switching to SaaS mode\");\n\n    const previousMode = this.currentConfig?.mode ?? null;\n    const serverConfig: ServerConfig = { url: saasServerUrl };\n\n    await invoke(\"set_connection_mode\", {\n      mode: \"saas\",\n      serverConfig,\n    });\n\n    this.currentConfig = {\n      mode: \"saas\",","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/Stirling-Tools/Stirling-PDF/blob/9ef20dcab80b85041912f045e17a6aea1d08f969/frontend/editor/src/desktop/services/connectionModeService.ts#L121-L157","documentation":"Thrown by connectionModeService.switchToSaaS when currentConfig.lock_connection_mode is true. This flag is set by provisioning (e.g. an MSI install pinned with STIRLING_SERVER_URL) to forbid the user from changing the connection target away from the provisioned server. The mode switch is rejected before any Rust command runs.","triggerScenarios":"A provisioned/managed desktop install where the admin locked connection mode, and the user (or a code path) calls switchToSaaS(). The provisioned config sets lock_connection_mode: true at load time.","commonSituations":"Enterprise MSI deployment with a fixed server URL; kiosk/single-tenant setup; code that auto-prompts 'sign in to Cloud' hitting a locked install.","solutions":["Do not call switchToSaaS on locked installs — check currentConfig.lock_connection_mode first and hide/disable the SaaS switch UI.","If a different server is genuinely required, have the admin re-provision the install with the new STIRLING_SERVER_URL (clearing the lock).","Surface a clear 'managed by your administrator' message instead of a raw error."],"exampleFix":"// before\nawait connectionModeService.switchToSaaS(url);\n\n// after: respect the lock\nconst cfg = await connectionModeService.getCurrentConfig();\nif (cfg.lock_connection_mode) {\n  notify('Connection mode is managed by your administrator.');\n  return;\n}\nawait connectionModeService.switchToSaaS(url);","handlingStrategy":"validation","validationCode":"const cfg = await connectionModeService.getCurrentConfig();\nif (cfg.lock_connection_mode) { notify('Connection mode is managed by your administrator.'); return; }","typeGuard":"function isConnectionModeLocked(e: unknown): e is Error {\n  return e instanceof Error && e.message === 'Connection mode is locked by provisioning';\n}","tryCatchPattern":"try { await connectionModeService.switchToSaaS(url); }\ncatch (e) {\n  if (isConnectionModeLocked(e)) { notify('Connection mode is managed by your administrator.'); return; }\n  throw e;\n}","preventionTips":["Check lock_connection_mode before rendering the SaaS-switch UI on managed installs.","Hide, not just disable, the switch on locked deployments to avoid dead UI.","Document provisioning/lock behaviour for admins."],"tags":["provisioning","connection-mode","mdm","desktop"],"backgroundTag":null,"analyzedSha":"9ef20dcab80b85041912f045e17a6aea1d08f969","analyzedAt":"2026-08-13T22:11:39.827Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}