m1k1o/neko · error
cannot access clipboard
Error message
cannot access clipboard
What it means
clipboardSet in server/internal/websocket/handler/clipboard.go rejects any incoming clipboard-set message when the sending session's profile lacks CanAccessClipboard. The neko server gates clipboard access behind a per-session permission so only authorized users may read or write the remote machine's clipboard. The permission check deliberately runs before the host check.
Source
Thrown at server/internal/websocket/handler/clipboard.go:12
package handler
import (
"errors"
"github.com/m1k1o/neko/server/pkg/types"
"github.com/m1k1o/neko/server/pkg/types/message"
)
func (h *MessageHandlerCtx) clipboardSet(session types.Session, payload *message.ClipboardData) error {
if !session.Profile().CanAccessClipboard {
return errors.New("cannot access clipboard")
}
if !session.IsHost() {
return errors.New("is not the host")
}
return h.desktop.ClipboardSetText(types.ClipboardText{
Text: payload.Text,
// TODO: Send HTML?
})
}
View on GitHub (pinned to b0f01cedea)
Solutions
- Grant CanAccessClipboard: true in the session's profile when creating the session (config or membership provider).
- Have the client hide/disable clipboard UI when its profile lacks the clipboard permission (profile is delivered to the client).
- Reconnect the session after changing profiles so the new profile takes effect.
- If using an external membership provider, verify it returns the clipboard flag correctly.
Example fix
// before
config.Member.Profile = types.MemberProfile{ CanWatch: true }
// after
config.Member.Profile = types.MemberProfile{ CanWatch: true, CanAccessClipboard: true } Defensive patterns
Strategy: validation
Validate before calling
// client-side, before sending clipboard data
if (!session.profile.canAccessClipboard) {
throw new Error('clipboard access not permitted for this profile')
} Type guard
function canAccessClipboard(session) {
return typeof session.profile === 'object' && session.profile != null && session.profile.canAccessClipboard === true
} Try / catch
try {
socket.emit('clipboard/set', { text })
} catch (e) {
if (e.message === 'cannot access clipboard') disableClipboardUI()
} Prevention
- Set CanAccessClipboard in the member profile at session creation time.
- Render clipboard UI conditionally based on the profile delivered to the client.
- Re-authenticate/reconnect after permission changes so profiles refresh.
- Audit external membership providers for correct flag mapping.
When it happens
Trigger: A WebSocket client sends a clipboard data message (handled by clipboardSet, dispatched from controlPaste or the anonymous clipboard handler) while session.Profile().CanAccessClipboard is false.
Common situations: Connecting a user whose member profile was created without CanAccessClipboard:true; an admin recently toggled profile permissions server-side but the client session was created earlier; embedding neko for read-only viewers who then attempt copy/paste into the remote desktop.
Understand the failure class
Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.
Related errors
AI-assisted analysis of m1k1o/neko@b0f01cedea (2026-09-01).
Data as JSON: /api/errors/fad331c8e4f1761a.
Report an issue: GitHub.