siyuan-note/siyuan · error

invalid raw SSE event declaration

Error message

invalid raw SSE event declaration

What it means

rawSSESchema validates that an endpoint's SSE declaration is exactly the canonical raw-SSE configuration: no named events declared, and the Raw definition deep-equals the RawSSEOptions() baseline. Any deviation — declaring events alongside a raw declaration, or customizing raw fields — is rejected as an invalid declaration. This keeps raw SSE an all-or-nothing mode so the generated schema and runtime validation agree.

Solutions

  1. Remove all entries from definition.Events when using raw SSE mode
  2. Use the exact defaults from RawSSEOptions() instead of customizing the Raw struct
  3. Declare either named events (evented mode) or raw mode, never both
  4. Regenerate the contract definition with the current library version

Example fix

// before
SSE: &SSEDefinition{Raw: RawSSEOptions().SSE.Raw, Events: []string{"progress"}}
// after
SSE: &SSEDefinition{Raw: RawSSEOptions().SSE.Raw}
Defensive patterns

Strategy: validation

Validate before calling

if (def.events?.length) throw new Error("raw SSE cannot declare events");
if (!deepEqual(def.raw, RawSSEOptions().SSE.Raw)) throw new Error("raw SSE definition customized");

Type guard

function isRawSSEDef(d) { return !!d?.raw && (!d.events || d.events.length === 0); }

Try / catch

try { schema = buildSSE(def); } catch (e) { if (String(e).includes("invalid raw SSE event declaration")) { def = { raw: RawSSEOptions().SSE.Raw }; schema = buildSSE(def); } else throw e; }

Prevention

When it happens

Trigger: BuildBundle (or the test) encounters an SSE definition with a non-empty Events list while Raw is set, or a Raw definition that differs in any field from RawSSEOptions().SSE.Raw (e.g. custom retry, comment, or event-name fields).

Common situations: Copy-pasting an evented SSE definition and toggling raw on without clearing Events; hand-editing the raw defaults; mixing old and new schema versions after an upgrade changed the raw baseline.

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/df3760d64c8d4678. Report an issue: GitHub.

Appendix: source

Thrown at kernel/apicontract/broadcast_protocol.go:32

}

type RawWebSocketDefinition struct {
	Frames               []int `json:"frames"`
	UpgradeErrorStatuses []int `json:"upgradeErrorStatuses"`
	EmptyClosedResponse  bool  `json:"emptyClosedResponse"`
}

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")

View on GitHub (pinned to 9f775e8a12)