moeru-ai/airi · warning
Clipboard API is unavailable
Error message
Clipboard API is unavailable
What it means
stage-render-error.vue builds a bug report and copies it to the clipboard via VueUse's useClipboard({ legacy: true }). isClipboardSupported is false when neither navigator.clipboard (async Clipboard API) nor document.execCommand('copy') (legacy fallback) is available. The code checks the flag before copying and throws this error so the UI can show it inside the bug report dialog.
Source
Thrown at packages/stage-ui/src/components/scenes/stage-render-error.vue:45
const bugReportSubmitError = shallowRef<unknown>()
function openBugReportDialog() {
bugReportDescription.value = t('stage.render-error.report-description', {
renderer: props.renderer,
modelId: props.modelId ?? 'unknown',
error: errorMessageFrom(props.error) ?? props.error.message,
})
bugReportSubmitError.value = undefined
showBugReportDialog.value = true
}
async function submitBugReport(payload: BugReportDialogSubmitPayload) {
bugReportSending.value = true
bugReportSubmitError.value = undefined
try {
if (!isClipboardSupported.value)
throw new Error('Clipboard API is unavailable')
await copy(payload.formattedReport)
showBugReportDialog.value = false
}
catch (error) {
bugReportSubmitError.value = error
}
finally {
bugReportSending.value = false
}
}
</script>
<template>
<div
:class="[
'absolute inset-0 z-20 p-6',
'flex items-center justify-center',View on GitHub (pinned to 677329427f)
Solutions
- Serve the app from a secure context: https:// or http://localhost / http://127.0.0.1.
- Grant clipboard-read/clipboard-write permission (Permissions-Policy header, or Electron session setPermissionRequestHandler).
- Update the embedded WebView/Chromium so navigator.clipboard exists.
- As a product fallback, render the report in a selectable textarea so users can copy manually when isClipboardSupported is false.
Example fix
// before
if (!isClipboardSupported.value)
throw new Error('Clipboard API is unavailable')
await copy(payload.formattedReport)
// after — degrade gracefully instead of throwing
if (!isClipboardSupported.value) {
manualCopyText.value = payload.formattedReport
bugReportSubmitError.value = new Error('Clipboard unavailable — copy the report text below manually.')
return
}
await copy(payload.formattedReport) Defensive patterns
Strategy: type-guard
Validate before calling
import { useClipboard } from '@vueuse/core'
const { copy, isSupported } = useClipboard({ legacy: true })
if (!isSupported.value) {
// render manual-copy fallback (textarea) instead of submitting to copy()
} Type guard
function isClipboardAvailable(): boolean {
return typeof navigator !== 'undefined'
&& ((navigator.clipboard != null && window.isSecureContext) || typeof document?.execCommand === 'function')
} Try / catch
try {
await copy(payload.formattedReport)
}
catch (error) {
// Firefox/permission rejections still throw even when isSupported is true
bugReportSubmitError.value = error
} Prevention
- Serve over https or localhost so navigator.clipboard exists.
- Always provide a manual copy fallback path for the bug report text.
- In Electron, allow clipboard in the session permission handler.
When it happens
Trigger: Submitting the bug report dialog in a non-secure context (page served over http:// on a non-localhost host), an old embedded WebView without the async clipboard API, or an environment where document.execCommand is also unavailable, making both the modern and legacy paths unsupported.
Common situations: Running stage-web over plain http on a LAN IP or inside a VM/remote preview; older Electron/Chromium WebView with permissions policies blocking clipboard; iframe sandbox without allow-clipboard-write; headless/automated browsers with clipboard disabled.
Related errors
- WebGPU is required for this model but is not available in yo
- Web Speech API is not available in this environment. It requ
- No audio stream available
- [chat-ws] ws error event:
AI-assisted analysis of moeru-ai/airi@677329427f (2026-08-18).
Data as JSON: /api/errors/f123ed63cfb635ae.
Report an issue: GitHub.