DTK0013: Unauthorized RPC Access
Message
Unauthorized access to method
{name}from client [{clientId}]
Cause
This error is thrown by the RPC resolver in createWsServer() when an untrusted WebSocket client attempts to call a protected RPC method. Any method whose name starts with anonymous: is exempt and callable before trust — that's the auth handshake (anonymous:devframe:auth and anonymous:devframe:auth:exchange). Every other method requires the client to be trusted.
A client becomes trusted through one of these mechanisms:
- Client auth is disabled (build mode,
clientAuth: false, orVITE_DEVTOOLS_DISABLE_CLIENT_AUTH=true) — all clients are auto-trusted. - One-time code exchange — an untrusted browser is shown a one-time code in the terminal, along with a
?devframe_otp=magic link. Entering the code (or opening the link) exchanges it viaanonymous:devframe:auth:exchangefor a node-issued bearer token; the browser persists that token and re-presents it (anonymous:devframe:auth) on reconnect. - Static auth tokens — the token matches one listed in
devtools.clientAuthTokensin your Vite config.
If none of these conditions are met, the client is untrusted and any call to a protected method triggers this error. A trusted browser can also hand its access back from Settings → Advanced → Revoke Access, which revokes its token and drops it to untrusted.
Example
An untrusted browser calling a protected method:
// The browser hasn't completed the auth handshake yet — it's untrusted.
await rpc.call('my-plugin:get-data')
// Error: Unauthorized access to method "my-plugin:get-data" from client [abc123]Fix
Authorize the browser. When an untrusted client connects, the dev-server terminal prints a one-time code and a magic link:
- Enter the code in the DevTools authorization prompt, or
- Open the magic link (
<origin>/?devframe_otp=<code>) — the client reads the code, exchanges it for a bearer token, and persists it for future reconnects.
For automated setups (CI, shared machines), configure static trusted tokens instead — a client presenting one via the devframe_auth_token connection parameter is trusted without the interactive step:
import { DevTools } from '@vitejs/devtools'
// vite.config.ts
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [
DevTools(),
],
devtools: {
enabled: true,
clientAuthTokens: ['your-trusted-token'],
},
})If you are developing locally and want to skip authentication entirely, see DTK0008 for how to disable client auth.
Source
packages/core/src/node/ws.ts— the WebSocket RPC resolver increateWsServer()throwsDTK0013when an untrusted client invokes a method that isn'tanonymous:-prefixed (devframe'sisAnonymousRpcMethod).