windmill-labs/windmill · error

<server error text> || Failed to sign multiplayer session

Error message

<server error text> || Failed to sign multiplayer session

What it means

signMultiplayerRequest's failure path: any non-OK response from POST /api/w/{workspace}/debug/sign_multiplayer causes the server's error text — or the fallback 'Failed to sign multiplayer session' when the body is empty — to be thrown. The multiplayer server will subsequently reject the WebSocket connection without a valid JWT, so collaboration cannot start.

Source

Thrown at frontend/src/lib/components/debug/debugUtils.ts:95

/**
 * Sign a multiplayer session request. Returns a JWT token that the
 * multiplayer server will verify before accepting the WebSocket connection.
 */
export async function signMultiplayerRequest(workspace: string): Promise<string> {
	if (!workspace) {
		throw new Error('No workspace selected')
	}

	const response = await fetch(`/api/w/${workspace}/debug/sign_multiplayer`, {
		method: 'POST',
		headers: { 'Content-Type': 'application/json' },
		body: JSON.stringify({})
	})

	if (!response.ok) {
		const errorText = await response.text()
		throw new Error(errorText || 'Failed to sign multiplayer session')
	}

	const data: { token: string } = await response.json()
	return data.token
}

/**
 * Get a user-friendly error message for debug errors
 */
export function getDebugErrorMessage(error: unknown): string {
	const message = error instanceof Error ? error.message : String(error)

	// Handle token verification errors from debugger
	if (message.includes('Token verification failed') || message.includes('Debug token required')) {
		if (message.includes('expired')) {
			return 'Debug session expired. Please try again.'
		}
		if (message.includes('Invalid JWT signature')) {

View on GitHub (pinned to e474e8803c)

Solutions

  1. Read the thrown text / network status to identify the rejection; for 401/403 refresh the login or permissions.
  2. Confirm the backend build supports sign_multiplayer (EE/multiplayer enabled) — a 404 means the route is absent.
  3. Retry after transient 5xx/proxy errors; check backend logs if persistent.
  4. Verify the workspace id exists and the user is a member.
Defensive patterns

Strategy: try-catch

Try / catch

try { const token = await signMultiplayerRequest(ws) } catch (e) { disableCollaboration((e as Error).message); }

Prevention

When it happens

Trigger: Non-2xx from /debug/sign_multiplayer: 401/403 (expired/insufficient token), 404 (workspace not found or route absent on this backend version), 5xx from backend or proxy, or empty error body triggering the fallback.

Common situations: Session token expired while the editor stayed open; user lacking multiplayer entitlement (EE feature); backend version without the sign_multiplayer route; reverse proxy 502/503 during deploys.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/dbb769422886b500. Report an issue: GitHub.