Stirling-Tools/Stirling-PDF · error · Error

Server configuration not found

Error message

Server configuration not found

What it means

Thrown on the remote-routing branch of getBaseUrlForOperation() when connectionModeService.getServerConfig() returns a falsy value. The remote branch is reached only when getExecutionTarget() !== 'local', so this means a remote/self-hosted-server target was chosen but no server configuration (URL + credentials) is persisted. The returned serverConfig.url is otherwise used verbatim (trailing slash stripped).

Source

Thrown at frontend/editor/src/desktop/services/operationRouter.ts:310

    const target = await this.getExecutionTarget(operation);

    if (target === "local") {
      // Use dynamically assigned port from backend service
      const backendUrl = tauriBackendService.getBackendUrl();
      if (!backendUrl) {
        throw new Error(
          "Backend URL not available - backend may still be starting",
        );
      }
      // Strip trailing slash to avoid double slashes in URLs
      return backendUrl.replace(/\/$/, "");
    }

    // Remote: get from server config
    const serverConfig = await connectionModeService.getServerConfig();
    if (!serverConfig) {
      console.warn("No server config found");
      throw new Error("Server configuration not found");
    }

    // Strip trailing slash to avoid double slashes in URLs
    return serverConfig.url.replace(/\/$/, "");
  }

  /**
   * Checks if we're currently in self-hosted mode
   */
  async isSelfHostedMode(): Promise<boolean> {
    const mode = await connectionModeService.getCurrentMode();
    return mode === "selfhosted";
  }

  /**
   * Checks if we're currently in SaaS mode
   */
  async isSaaSMode(): Promise<boolean> {

View on GitHub (pinned to 9ef20dcab8)

Solutions

  1. Ensure the user has completed server onboarding (connectionModeService should have a non-null config) before allowing remote-targeted operations.
  2. Check that getServerConfig() is awaited and its underlying store has loaded before the router runs.
  3. If the config was intentionally cleared, force the mode back to local so getExecutionTarget returns 'local' instead of remote.
  4. Surface a 'please reconnect your server' prompt in the UI when this throws, rather than a raw error.

Example fix

// before
const serverConfig = await connectionModeService.getServerConfig();
if (!serverConfig) {
  throw new Error("Server configuration not found");
}
return serverConfig.url.replace(/\/$/, "");

// after — typed error + clear recovery path for the UI
const serverConfig = await connectionModeService.getServerConfig();
if (!serverConfig) throw new NoServerConfigError();
return serverConfig.url.replace(/\/$/, "");
Defensive patterns

Strategy: validation

Validate before calling

import { connectionModeService } from "@app/desktop/services/connectionModeService";

async function hasServerConfig(): Promise<boolean> {
  return (await connectionModeService.getServerConfig()) != null;
}
// guard remote-targeted operations: if (!await hasServerConfig()) promptReconnect();

Type guard

function isNoServerConfig(e: unknown): boolean {
  return e instanceof Error && /Server configuration not found/.test(e.message);
}

Try / catch

try {
  const base = await router.getBaseUrlForOperation(operation);
} catch (e) {
  if (isNoServerConfig(e)) { promptReconnectServer(); return; }
  throw e;
}

Prevention

When it happens

Trigger: getExecutionTarget() returns a remote target but getServerConfig() yields null/undefined. Happens when the connection-mode store has no saved server (user never connected) or the persisted config was cleared/corrupted while the mode still implies a remote server.

Common situations: User selected self-hosted/remote mode but never completed the 'connect to server' flow; a config migration reset the stored server config; the config load is async and was queried before it resolved.

Related errors


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