siyuan-note/siyuan · error
proxy output requires a protocol declaration
Error message
proxy output requires a protocol declaration: %s
What it means
validateProxyDefinition enforces that proxy configuration is all-or-nothing: a Definition must either declare both ProxyOutput and a Proxy protocol, or neither. If one side is set without the other, it returns "proxy output requires a protocol declaration: %s" naming the endpoint. This catches definitions that claim proxy output but lack the HTTP/EventSource/WebSocket proxy spec (or vice versa), which would leave the runtime unable to construct the upstream transport.
Solutions
- Set both fields consistently: Output: ProxyOutput together with a non-nil Proxy (HTTPProxy, EventSourceProxy, or WebSocketProxy)
- If the endpoint is not a proxy, remove the Proxy declaration instead of leaving it set with a non-proxy Output
- Or keep Proxy and add the missing Output: ProxyOutput to the definition
- Add a unit test mirroring TestProxyDefinitionRejectsUnknownProtocol so BuildBundle fails fast with the endpoint name
Example fix
// before
Definition{Name: "upstream", Output: ProxyOutput}
// after
Definition{Name: "upstream", Output: ProxyOutput, Proxy: &ProxyDeclaration{Kind: HTTPProxy}} Defensive patterns
Strategy: validation
Validate before calling
func proxyDeclarationIsConsistent(d Definition) bool { return (d.Output == ProxyOutput) == (d.Proxy != nil) } Try / catch
if err := BuildBundle(defs); err != nil { if strings.Contains(err.Error(), "proxy output requires a protocol declaration") { logDefectDefinition(err); return }; return err } — better: run validateProxyDefinition-equivalent checks in unit tests before BuildBundle Prevention
- Always set Output and Proxy together when introducing a proxy endpoint
- Remove both fields together when converting an endpoint away from proxying
- Mirror the validator's checks in unit tests like TestProxyDefinitionRejectsUnknownProtocol
- Review diff hibernation: partial copy-paste of Definition structs is the usual culprit
When it happens
Trigger: Building a bundle (BuildBundle) with a Definition whose Output is ProxyOutput but whose Proxy field is nil; or conversely setting Definition.Proxy while leaving Output as a regular JSON output — surfaced by TestProxyDefinitionRejectsUnknownProtocol-style tests and at bundle construction time.
Common situations: A developer adds Output: ProxyOutput but forgets to fill Proxy: &Proxy{Kind: ...}; a refactor switches an endpoint to proxy mode and removes Output but forgets to remove Proxy; copy-pasted definitions partially updated; a code path builds Definitions programmatically and conditionally sets only one of the two fields.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- A public HTTPS OIDC redirect URL is required for remote…
- agent HTTP tools support HTTP, HTTPS and SOCKS5 proxies
- Argon2id Iterations too high (maximum 10)
- Argon2id Memory too high (maximum 256 MB)
- Argon2id Parallelism must be between 1 and 16
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/f8d68d915b9486a0.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/apicontract/proxy_protocol.go:91
panic("invalid upstream proxy status")
}
return response.httpStatus
}
if response.directJSON {
if response.httpStatus != 400 && response.httpStatus != 502 {
panic("undeclared proxy rejection status")
}
return response.httpStatus
}
if response.code == 0 {
panic("proxy response requires a stream or rejection")
}
return 200
}
func validateProxyDefinition(definition Definition) error {
if (definition.Output == ProxyOutput) != (definition.Proxy != nil) {
return fmt.Errorf("proxy output requires a protocol declaration: %s", definition.Name)
}
if definition.Proxy == nil {
return nil
}
if definition.Proxy.Kind != HTTPProxy && definition.Proxy.Kind != EventSourceProxy && definition.Proxy.Kind != WebSocketProxy {
return fmt.Errorf("unsupported proxy protocol: %s", definition.Proxy.Kind)
}
if definition.Data != reflect.TypeFor[ProxyFailure]() || definition.DataOnError || definition.ErrorStatus != 0 || definition.SSE != nil || definition.WebSocket != nil {
return fmt.Errorf("invalid proxy response options: %s", definition.Name)
}
want := ProxyOptions(definition.Proxy.Kind).Proxy
if !reflect.DeepEqual(want, definition.Proxy) {
return fmt.Errorf("invalid proxy protocol declaration: %s", definition.Name)
}
return nil
}
// validateProxyHTTPResponse 按媒体类型区分上游字节和内核准入失败,同状态不代表同协议。View on GitHub (pinned to 9f775e8a12)