oven-sh/bun · error · TypeError

bun-svelte-plugin: forceSide must be either 'client' or 'ser

Error message

bun-svelte-plugin: forceSide must be either 'client' or 'server', got ${opts.forceSide}

What it means

validateOptions() accepts forceSide only as exactly 'client' or 'server'. A correctly-typed string with any other value — 'both', 'ssr', 'hybrid', trailing spaces, wrong casing like 'Client' — fails the switch and throws this TypeError naming the offending value.

Source

Thrown at packages/bun-plugin-svelte/src/options.ts:47

}

/**
 * @internal
 */
export function validateOptions(options: unknown): asserts options is SvelteOptions {
  assert(options && typeof options === "object", new TypeError("bun-svelte-plugin: options must be an object"));
  const opts = options as Record<keyof SvelteOptions, unknown>;

  if (opts.forceSide != null) {
    if (typeof opts.forceSide !== "string") {
      throw new TypeError("bun-svelte-plugin: forceSide must be a string, got " + typeof opts.forceSide);
    }
    switch (opts.forceSide) {
      case "client":
      case "server":
        break;
      default:
        throw new TypeError(`bun-svelte-plugin: forceSide must be either 'client' or 'server', got ${opts.forceSide}`);
    }
  }

  if (opts.compilerOptions) {
    if (typeof opts.compilerOptions !== "object") {
      throw new TypeError("bun-svelte-plugin: compilerOptions must be an object");
    }
  }
}

/**
 * @internal
 */
export function getBaseCompileOptions(pluginOptions: SvelteOptions, config: Partial<BuildConfig>): CompileOptions {
  let {
    development = false,
    compilerOptions: { customElement, runes, modernAst, namespace } = kEmptyObject as OverrideCompileOptions,
  } = pluginOptions;

View on GitHub (pinned to 8c5296ac45)

Solutions

  1. Use exactly 'client' or 'server'
  2. Trim/lowercase values sourced from env vars or config before passing
  3. Omit forceSide to use the plugin's automatic side detection

Example fix

// before
Bun.svelte({ forceSide: 'both' });

// after
Bun.svelte({ forceSide: 'client' }); // or 'server'
Defensive patterns

Strategy: type-guard

Validate before calling

const FORCE_SIDES = ['client', 'server'] as const;
function normalizeForceSide(v: unknown): 'client' | 'server' | undefined {
  if (typeof v !== 'string') return undefined;
  const s = v.trim().toLowerCase();
  return (FORCE_SIDES as readonly string[]).includes(s) ? (s as 'client' | 'server') : undefined;
}

Type guard

const isValidForceSide = (v: unknown): v is 'client' | 'server' =>
  v === 'client' || v === 'server';

Prevention

When it happens

Trigger: Bun.svelte({ forceSide: 'both' }), forceSide: 'SSR', forceSide: 'client ' (trailing whitespace), or values read from env vars/config files without normalization.

Common situations: Users expecting a 'both'/'universal' mode that does not exist; env-derived values with casing or whitespace differences; copy-pasted options from other Svelte tooling (e.g. vite-plugin-svelte semantics).

Related errors


AI-assisted analysis of oven-sh/bun@8c5296ac45 (2026-08-16). Data as JSON: /api/errors/bf34793510a85b77. Report an issue: GitHub.