Molunerfinn/PicGo · warning
Failed to get window state
Error message
Failed to get window state
What it means
getWindowState throws when the GET_WINDOW_STATE RPC fails, meaning no { isMaximized } envelope came back from the main process. The main handler (src/main/events/rpc/routes/system.ts:16) resolves the sender BrowserWindow and reads isMaximized(); if the handler throws (e.g. event.sender is destroyed) the RPC server converts it to a failure envelope and the adapter raises this Error. The literal text is the fallback when result.error is empty.
Source
Thrown at src/renderer/adapters/window-controls.ts:9
import { CLOSE_WINDOW, MAXIMIZE_WINDOW, MINIMIZE_WINDOW } from '#/events/constants'
import { IRPCActionType } from '~/universal/types/enum'
import { invokeRPC, sendToMain } from '@/utils/dataSender'
export const windowControlsAdapter = {
async getWindowState () {
const result = await invokeRPC<{ isMaximized: boolean }>(IRPCActionType.GET_WINDOW_STATE)
if (!result.success) {
throw new Error(result.error || 'Failed to get window state')
}
return result.data
},
closeWindow () {
sendToMain(CLOSE_WINDOW)
},
maximizeWindow () {
sendToMain(MAXIMIZE_WINDOW)
},
minimizeWindow () {
sendToMain(MINIMIZE_WINDOW)
},
openMiniWindow () {
sendToMain('openMiniWindow')
}
}
View on GitHub (pinned to 07ec7068a5)
Solutions
- Guard the caller: skip window-state queries when the window is closing or the app is shutting down
- Default to { isMaximized: false } in the calling component instead of letting the rejection propagate to the UI
- Log result.error to confirm whether the sender window was destroyed; if so, re-query after the window is ready
- Ensure rpcServer.start() has run before any renderer issues GET_WINDOW_STATE (normal app boot does this)
Example fix
// before
const { isMaximized } = await windowControlsAdapter.getWindowState()
// after
let isMaximized = false
try {
isMaximized = (await windowControlsAdapter.getWindowState())?.isMaximized ?? false
} catch {
// window gone or main busy; fall back to non-maximized
} Defensive patterns
Strategy: fallback
Validate before calling
if (!document.hasFocus() || window.isClosed) {
return { isMaximized: false }
} Type guard
function isWindowState(v: unknown): v is { isMaximized: boolean } {
return typeof v === 'object' && v !== null && typeof (v as { isMaximized?: unknown }).isMaximized === 'boolean'
} Try / catch
try {
state = await windowControlsAdapter.getWindowState()
} catch {
state = { isMaximized: false } // safe default
} Prevention
- Only query window state while the window is alive and the app is fully booted
- Default isMaximized to false on any failure instead of rejecting UI updates
- Debounce state queries during window transitions (maximize/close)
- Verify RPC server startup ordering in main before renderer windows load
When it happens
Trigger: Calling getWindowState() from a renderer whose WebContents is being destroyed/closed (BrowserWindow.fromWebContents returns undefined or isMaximized throws), or when the main-process RPC server is not running (app quitting) so invokeRPC fails/returns failure.
Common situations: Window restore/maximize logic running during window close or app shutdown; a minimized/tray-only session where the sender window no longer exists; race between renderer mount and main-process RPC server start().
Related errors
- Toolbox fix failed
- Setting window not found
- Failed to load provider configs
- Failed to select provider config
- Failed to delete provider config
AI-assisted analysis of Molunerfinn/PicGo@07ec7068a5 (2026-08-30).
Data as JSON: /api/errors/f5525045b8f58098.
Report an issue: GitHub.