Molunerfinn/PicGo · error

Clipboard API is unavailable.

Error message

Clipboard API is unavailable.

What it means

copyToClipboard explicitly throws when the browser Clipboard API (navigator.clipboard.writeText) is missing. This API only exists in secure contexts (HTTPS or localhost) and requires window focus and permission; in Electron it can also be missing in offscreen or unloaded-context windows. The function checks availability before writing and throws this Error otherwise.

Source

Thrown at src/renderer/components/independent-window/utils.ts:15

export function resolveIndependentWindowErrorMessage(
  error: unknown,
  fallback: string
) {
  if (error instanceof Error) {
    const message = error.message.trim()
    return message.length > 0 ? message : fallback
  }

  return fallback
}

export async function copyToClipboard(value: string) {
  if (!navigator.clipboard?.writeText) {
    throw new Error("Clipboard API is unavailable.")
  }

  await navigator.clipboard.writeText(value)
}

View on GitHub (pinned to 07ec7068a5)

Solutions

  1. Use Electron's clipboard.writeText via IPC (the project's COPY_TEXT RPC / clipboard API) which does not depend on the web Clipboard API
  2. Ensure the window is loaded over a secure context and is focused before calling; call copyToClipboard from a user-gesture handler
  3. Avoid rendering inside cross-origin iframes without clipboard-write permission; set Permissions-Policy to allow clipboard-write
  4. Fall back to a legacy document.execCommand('copy') path when navigator.clipboard is absent

Example fix

// before
await copyToClipboard(value)
// after
try {
  await copyToClipboard(value)
} catch {
  // fallback: main-process clipboard via IPC
  sendToMain(IRPCActionType.COPY_TEXT, value)
}
Defensive patterns

Strategy: fallback

Validate before calling

if (typeof navigator.clipboard?.writeText !== 'function') {
  // route through Electron main-process clipboard instead
  sendToMain(IRPCActionType.COPY_TEXT, value)
  return
}

Type guard

function clipboardAvailable(n: Navigator): n is Navigator & { clipboard: Clipboard } {
  return typeof n.clipboard?.writeText === 'function'
}

Try / catch

try {
  await copyToClipboard(value)
} catch (e) {
  if ((e as Error).message === 'Clipboard API is unavailable.') {
    sendToMain(IRPCActionType.COPY_TEXT, value)
  }
}

Prevention

When it happens

Trigger: Calling copyToClipboard in a window/context where navigator.clipboard is undefined or writeText is absent: insecure origin, iframe without clipboard permission (Permissions-Policy clipboard-write), document not focused, or older/odd webview lacking the API.

Common situations: Independent (mini) windows loading content via file:// or http:// instead of the app origin; copying immediately after window open before the document gains focus; embedded webviews with restrictive permissions; browsers (Safari) requiring user-gesture-initiated clipboard writes.


AI-assisted analysis of Molunerfinn/PicGo@07ec7068a5 (2026-08-30). Data as JSON: /api/errors/b3c88d6c3e3c8311. Report an issue: GitHub.