siyuan-note/siyuan · error

invalid raw WebSocket declaration

Error message

invalid raw WebSocket declaration

What it means

rawWebSocketSchema validates that a WebSocket declaration in raw mode is untouched: Incoming and Outgoing typed schemas must be nil, FailureStatus must be zero, and Raw must deep-equal RawWebSocketOptions().WebSocket.Raw. Any typed-channel declaration or customized raw field makes the declaration invalid. Raw mode is a fixed wire passthrough, so customizations are not permitted.

Solutions

  1. Remove Incoming and Outgoing schema declarations from the raw WebSocket definition
  2. Reset FailureStatus to 0
  3. Restore Raw to the exact value produced by RawWebSocketOptions().WebSocket.Raw
  4. Declare a normal typed WebSocket endpoint instead if custom schemas are needed

Example fix

// before
WebSocket: &WebSocketDefinition{Raw: customRaw, Incoming: &Schema{Type: "object"}}
// after
WebSocket: RawWebSocketOptions().WebSocket
Defensive patterns

Strategy: validation

Validate before calling

if (def.incoming || def.outgoing || def.failureStatus) throw new Error("raw WebSocket cannot declare typed schemas");
if (!deepEqual(def.raw, RawWebSocketOptions().WebSocket.Raw)) throw new Error("raw WebSocket definition customized");

Type guard

function isRawWSDef(d) { return !!d?.raw && !d.incoming && !d.outgoing && !d.failureStatus; }

Try / catch

try { schema = buildWS(def); } catch (e) { if (String(e).includes("invalid raw WebSocket declaration")) { def = RawWebSocketOptions().WebSocket; schema = buildWS(def); } else throw e; }

Prevention

When it happens

Trigger: BuildBundle processes an endpoint whose WebSocket definition sets Incoming/Outgoing message schemas, sets a FailureStatus, or modifies Raw fields (Frames list, UpgradeErrorStatuses, EmptyClosedResponse) away from the canonical raw defaults.

Common situations: Declaring typed message contracts and raw frames together by mistake; copying a normal (evented) WebSocket definition and adding Raw: true; changing allowed frame types to suit a custom protocol.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/acb2783035cb3bd5. Report an issue: GitHub.

Appendix: source

Thrown at kernel/apicontract/broadcast_protocol.go:39

func RawSSEOptions() ResponseOptions {
	return ResponseOptions{Output: SSEOutput, SSE: &SSEDefinition{Raw: &RawSSEDefinition{EventNames: "dynamic", DataEncoding: "raw", ID: true, Retry: true}}}
}

func RawWebSocketOptions() ResponseOptions {
	return ResponseOptions{Output: WebSocketOutput, WebSocket: &WebSocketDefinition{Raw: &RawWebSocketDefinition{Frames: []int{1, 2, 8, 9, 10}, UpgradeErrorStatuses: []int{400, 403, 405, 500}, EmptyClosedResponse: true}}}
}

func rawSSESchema(definition *SSEDefinition) (*SSESchema, error) {
	if len(definition.Events) != 0 || !reflect.DeepEqual(definition.Raw, RawSSEOptions().SSE.Raw) {
		return nil, fmt.Errorf("invalid raw SSE event declaration")
	}
	return &SSESchema{Raw: definition.Raw}, nil
}

func rawWebSocketSchema(definition *WebSocketDefinition) (*WebSocketSchema, error) {
	if definition.Incoming != nil || definition.Outgoing != nil || definition.FailureStatus != 0 || !reflect.DeepEqual(definition.Raw, RawWebSocketOptions().WebSocket.Raw) {
		return nil, fmt.Errorf("invalid raw WebSocket declaration")
	}
	return &WebSocketSchema{Incoming: &Schema{Type: "string", Format: "binary"}, Outgoing: &Schema{Type: "string", Format: "binary"}, Raw: definition.Raw}, nil
}

func validateRawWebSocketHTTP(schema *WebSocketSchema, status int, contentType string, payload []byte) (bool, error) {
	if schema.Raw == nil {
		return false, nil
	}
	if status == 101 {
		if len(payload) != 0 {
			return true, fmt.Errorf("WebSocket upgrade cannot contain a body")
		}
		return true, nil
	}
	if status == 200 && len(payload) == 0 && schema.Raw.EmptyClosedResponse {
		return true, nil
	}
	media, _, _ := mime.ParseMediaType(contentType)

View on GitHub (pinned to 9f775e8a12)