Skip to content

bug: Copy Config and Copy Key buttons on API Keys page do not copy to clipboard #677

Description

@vybe

Summary

The "Copy Config" button (copies full MCP JSON config) and the copy icon button (copies the raw API key) on the API Keys page (/api-keys) do not reliably copy to clipboard. Clicking them appears to do nothing — no content lands on the clipboard and no error is shown to the user.

Context

Both copy actions use navigator.clipboard.writeText() exclusively, with errors caught silently via console.error only. The Clipboard API can fail in several legitimate scenarios (modal focus trap, permission denied, non-secure context), and there is no fallback mechanism or user-visible error feedback.

Location: src/frontend/src/views/ApiKeys.vue

  • copyMcpConfig() — line 542
  • copyApiKey() — line 530

Root cause:

  • navigator.clipboard.writeText() can throw when the document does not have focus (e.g., inside a modal overlay), when clipboard permission is denied, or on non-HTTPS non-localhost contexts
  • No execCommand('copy') fallback
  • Error is swallowed silently — user sees no feedback that copy failed
  • The "Copied!" visual state may flip even on failure (before the async rejection)

Steps to Reproduce

  1. Go to /api-keys
  2. Create a new key or trigger the key display modal
  3. Click Copy Config or the copy icon button next to the key
  4. Attempt to paste — clipboard is empty or still holds previous content

Acceptance Criteria

  • Clicking "Copy Config" reliably copies the MCP JSON config to clipboard
  • Clicking the copy icon reliably copies the raw API key to clipboard
  • When clipboard write fails, a fallback (e.g., execCommand('copy') via a temporary textarea) is attempted
  • If both methods fail, a visible user-facing error is shown (toast or inline message) instructing the user to copy manually
  • The "Copied!" confirmation state only fires on confirmed success, not on async failure

Technical Notes

Add a shared copyToClipboard(text) utility (e.g., in src/frontend/src/utils/clipboard.js) that:

  1. Tries navigator.clipboard.writeText(text)
  2. Falls back to document.execCommand('copy') via a temporary off-screen <textarea>
  3. Returns a boolean indicating success

Both copyMcpConfig and copyApiKey should use this utility and surface an error toast on false.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions