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

  1. Grant CanAccessClipboard: true in the session's profile when creating the session (config or membership provider).
  2. Have the client hide/disable clipboard UI when its profile lacks the clipboard permission (profile is delivered to the client).
  3. Reconnect the session after changing profiles so the new profile takes effect.
  4. 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

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.