Stirling-Tools/Stirling-PDF · warning · Error

Connection mode is locked by provisioning

Error message

Connection mode is locked by provisioning

What it means

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.

Solutions

  1. Do not call switchToSaaS on locked installs — check currentConfig.lock_connection_mode first and hide/disable the SaaS switch UI.
  2. If a different server is genuinely required, have the admin re-provision the install with the new STIRLING_SERVER_URL (clearing the lock).
  3. Surface a clear 'managed by your administrator' message instead of a raw error.

Example fix

// before
await connectionModeService.switchToSaaS(url);

// after: respect the lock
const cfg = await connectionModeService.getCurrentConfig();
if (cfg.lock_connection_mode) {
  notify('Connection mode is managed by your administrator.');
  return;
}
await connectionModeService.switchToSaaS(url);
Defensive patterns

Strategy: validation

Validate before calling

const cfg = await connectionModeService.getCurrentConfig();
if (cfg.lock_connection_mode) { notify('Connection mode is managed by your administrator.'); return; }

Type guard

function isConnectionModeLocked(e: unknown): e is Error {
  return e instanceof Error && e.message === 'Connection mode is locked by provisioning';
}

Try / catch

try { await connectionModeService.switchToSaaS(url); }
catch (e) {
  if (isConnectionModeLocked(e)) { notify('Connection mode is managed by your administrator.'); return; }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: Enterprise MSI deployment with a fixed server URL; kiosk/single-tenant setup; code that auto-prompts 'sign in to Cloud' hitting a locked install.

Related errors


AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13). Data as JSON: /api/errors/fe1002e9ff7dd535. Report an issue: GitHub.

Appendix: source

Thrown at frontend/editor/src/desktop/services/connectionModeService.ts:139

      this.currentConfig = config;
      this.configLoadedOnce = true;
    } catch (error) {
      console.error("Failed to load connection config:", error);
      // Default to local mode on error — safer than showing SaaS UI for a
      // desktop app whose bundled backend is always available.
      this.currentConfig = {
        mode: "local",
        server_config: null,
        lock_connection_mode: false,
      };
      this.configLoadedOnce = true;
    }
  }

  async switchToSaaS(saasServerUrl: string): Promise<void> {
    if (this.currentConfig?.lock_connection_mode) {
      throw new Error("Connection mode is locked by provisioning");
    }

    // Clear local-only flag and expiry-prompted flag when signing in
    localStorage.removeItem(LOCAL_MODE_STORAGE_KEY);
    localStorage.removeItem(JWT_EXPIRED_PROMPTED_KEY);

    console.log("Switching to SaaS mode");

    const previousMode = this.currentConfig?.mode ?? null;
    const serverConfig: ServerConfig = { url: saasServerUrl };

    await invoke("set_connection_mode", {
      mode: "saas",
      serverConfig,
    });

    this.currentConfig = {
      mode: "saas",

View on GitHub (pinned to 9ef20dcab8)