BloopAI/vibe-kanban · error
Failed to copy repository path
Error message
Failed to copy repository path
What it means
This error is thrown by the RepoCopyPath workspace action after navigator.clipboard.writeText(repo.path) fails. The Clipboard API is async and rejects when the document is not focused, permissions are denied, or the browser context is insecure (non-HTTPS/localhost). The action catches the low-level error, logs it, and rethrows a generic Error so callers see a consistent message.
Source
Thrown at packages/web-core/src/shared/actions/index.ts:1111
},
},
// === Repo-specific Actions (for command bar when selecting a repo) ===
RepoCopyPath: {
id: 'repo-copy-path',
label: 'Copy Repo Path',
icon: CopyIcon,
requiresTarget: ActionTargetType.GIT,
isVisible: (ctx) => ctx.hasWorkspace && ctx.hasGitRepos,
execute: async (_ctx, _workspaceId, repoId) => {
try {
const repo = await repoApi.getById(repoId);
if (repo?.path) {
await navigator.clipboard.writeText(repo.path);
}
} catch (err) {
console.error('Failed to copy repo path:', err);
throw new Error('Failed to copy repository path');
}
},
},
RepoOpenInIDE: {
id: 'repo-open-in-ide',
label: 'Open Repo in IDE',
icon: DesktopIcon,
requiresTarget: ActionTargetType.GIT,
isVisible: (ctx) => ctx.hasWorkspace && ctx.hasGitRepos,
execute: async (_ctx, _workspaceId, repoId) => {
try {
const response = await repoApi.openEditor(repoId, {
editor_type: null,
file_path: null,
});
if (response.url) {
window.open(response.url, '_blank');View on GitHub (pinned to 4deb7eca8f)
Solutions
- Retry the copy synchronously inside the user-gesture handler so the document is focused when writeText runs.
- Serve the app over HTTPS or localhost — navigator.clipboard is undefined on insecure origins.
- Check navigator.permissions.query({name:'clipboard-write'}) and prompt the user to grant clipboard access.
- Add a fallback using document.execCommand('copy') with a temporary textarea when the async API is unavailable.
- If repo.path is empty/stale, refresh the repository record via repoApi.getById before copying.
Example fix
// before
await navigator.clipboard.writeText(repo.path);
// after
if (navigator.clipboard && document.hasFocus()) {
await navigator.clipboard.writeText(repo.path);
} else {
const ta = document.createElement('textarea');
ta.value = repo.path;
document.body.appendChild(ta);
ta.select();
document.execCommand('copy');
ta.remove();
} Defensive patterns
Strategy: fallback
Validate before calling
// before copying
if (!navigator.clipboard) throw new Error('Clipboard API unavailable (insecure context)');
if (!repo?.path) throw new Error('Repository has no path to copy');
const perm = await navigator.permissions?.query({ name: 'clipboard-write' });
if (perm && perm.state === 'denied') throw new Error('Clipboard write permission denied'); Type guard
function canUseClipboard(win: Window): win is Window & { navigator: Navigator & { clipboard: Clipboard } } {
return 'clipboard' in win.navigator && win.isSecureContext;
} Try / catch
try {
await navigator.clipboard.writeText(repo.path);
} catch (err) {
console.error('Failed to copy repo path:', err);
fallbackCopyViaExecCommand(repo.path); // textarea + execCommand('copy')
} Prevention
- Only invoke clipboard writes directly inside a user-gesture handler.
- Serve the app over HTTPS or localhost (secure context).
- Add allow="clipboard-write" when embedding the app in an iframe.
- Keep an execCommand('copy') fallback for unsupported browsers.
When it happens
Trigger: Executing the RepoCopyPath action when repoApi.getById(repoId) returns a repo with a path, but navigator.clipboard.writeText rejects — e.g. document lacks focus, clipboard-write permission denied via Permissions API, iframe without allow="clipboard-write", or page served over plain HTTP.
Common situations: Clicking the copy-path action in a window that lost focus (async delay between click and write), running the local web app over http:// on a LAN IP instead of localhost, embedding the app in an iframe, or browsers blocking clipboard access due to user-denied permission prompts.
Related errors
AI-assisted analysis of BloopAI/vibe-kanban@4deb7eca8f (2026-08-29).
Data as JSON: /api/errors/c27c1de4d1c72272.
Report an issue: GitHub.