stablyai/orca · error · Error

Invalid Active Server preference

Error message

Invalid Active Server preference

What it means

Thrown by the settings:set-active-runtime-environment-preference handler when args.environmentId is neither null nor a string. The handler then trims a string value and resolves it via resolveEnvironment, so the type check is the first guard against malformed IPC input (e.g. a number, object, or undefined payload shape).

Source

Thrown at src/main/ipc/settings.ts:286

      if (typeof afterValue !== 'boolean') {
        // No non-bool whitelist entries today; skip rather than guess.
        continue
      }
      track('settings_changed', {
        setting_key: key as SettingsChangedKey,
        value_kind: 'bool'
      })
    }

    return result
  })

  ipcMain.handle(
    'settings:set-active-runtime-environment-preference',
    (event, args: { environmentId?: unknown }): GlobalSettings => {
      const requestedEnvironmentId = args?.environmentId
      if (requestedEnvironmentId !== null && typeof requestedEnvironmentId !== 'string') {
        throw new Error('Invalid Active Server preference')
      }
      const requestedId = requestedEnvironmentId?.trim() || null
      const environmentId =
        requestedId === null ? null : resolveEnvironment(app.getPath('userData'), requestedId).id
      return store.updateSettings(
        { activeRuntimeEnvironmentId: environmentId },
        { notifyListeners: true, originWebContentsId: event.sender.id }
      )
    }
  )

  ipcMain.handle('settings:listFonts', () => {
    return listSystemFontFamilies()
  })

  ipcMain.handle('settings:previewGhosttyImport', () => {
    return previewGhosttyImport(store)
  })

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Always send environmentId as either a string id or explicitly null — never undefined or other types.
  2. Type the IPC call site narrowly (environmentId: string | null) and lint against unknown.
  3. In the renderer, coerce: const id = value == null ? null : String(value).
  4. Add a runtime guard in the renderer that blocks non-string/non-null before invoking.

Example fix

// before
ipc.invoke('settings:set-active-runtime-environment-preference', { environmentId: selected })

// after
const environmentId = selected == null ? null : typeof selected === 'string' ? selected : null
ipc.invoke('settings:set-active-runtime-environment-preference', { environmentId })
Defensive patterns

Strategy: type-guard

Validate before calling

function coerceActiveServerPreference(value: unknown): string | null {
  if (value === null) return null
  if (typeof value === 'string') return value
  return null // refuse undefined/numbers/objects
}

const environmentId = coerceActiveServerPreference(selected)
await ipc.invoke('settings:set-active-runtime-environment-preference', { environmentId })

Type guard

function isNullableStringId(value: unknown): value is string | null {
  return value === null || typeof value === 'string'
}

Try / catch

try {
  await ipc.invoke('settings:set-active-runtime-environment-preference', { environmentId })
} catch (e) {
  if (/Invalid Active Server/.test((e as Error).message)) {
    showError('Pick a server from the list, or clear the selection.')
  } else throw e
}

Prevention

When it happens

Trigger: Invoking the IPC with environmentId as a number (e.g. 0), an object, an array, or boolean. Also when undefined is passed where the renderer intended null (note: undefined passes the check because the guard only rejects non-null non-string values — undefined is not null and not a string, so it is rejected).

Common situations: Renderer bug sending the raw value of an uncontrolled input; a serialization layer that drops null to undefined; a typed caller that widened the field to unknown without narrowing.

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/d9cdad90a522d67c. Report an issue: GitHub.