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
- Remove Incoming and Outgoing schema declarations from the raw WebSocket definition
- Reset FailureStatus to 0
- Restore Raw to the exact value produced by RawWebSocketOptions().WebSocket.Raw
- 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
- Raw mode and typed Incoming/Outgoing schemas are mutually exclusive
- Reset FailureStatus for raw endpoints
- Use RawWebSocketOptions() as the single source of truth
- Re-run bundle builds in CI to catch declaration drift
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
- createEmptyParagraph must be a boolean
- endpoint does not declare raw WebSocket frames
- Field [ ] has an invalid type
- Field [ ] has an invalid value
- Field [ ] is required
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)