siyuan-note/siyuan · error
invalid plugin service HTTP status
Error message
invalid plugin service HTTP status: %d
What it means
validatePluginServiceStatus checks that a plugin service response status is a valid HTTP code (100-999) and also that it is permitted for the selected PluginServiceMode. This specific error fires when the status integer falls outside 100-999 (zero or negative values already normalized to 200 by StreamPluginService, so this typically comes from a raw, unvalidated status). Callers include StreamPluginService (panics), pluginServiceStatus, and ValidatePluginServiceResponse.
Solutions
- Pass a valid HTTP status (100-999) to StreamPluginService; omit it (or pass <= 0) to get the 200 default
- Clamp or validate computed status values before constructing the response
- Check upstream proxies/forwarded codes and map anything outside 100-999 to a standard status
Example fix
// before
status := baseStatus + delta*1000
resp := apicontract.StreamPluginService(apicontract.PluginServiceJSON, status, serve)
// after
if status < 100 || status > 999 {
status = http.StatusInternalServerError
}
resp := apicontract.StreamPluginService(apicontract.PluginServiceJSON, status, serve) Defensive patterns
Strategy: validation
Validate before calling
func validStatus(s int) bool { return s >= 100 && s <= 999 }
if !validStatus(status) { status = http.StatusInternalServerError } Try / catch
func serve(mode apicontract.PluginServiceMode, status int) (r apicontract.Response[apicontract.PluginServiceContent]) {
defer func() { if rec := recover(); rec != nil { log.Printf("status rejected: %v", rec); r = fallback(mode) } }()
return apicontract.StreamPluginService(mode, status, handler)
} Prevention
- Use net/http status constants instead of raw arithmetic on codes
- Rely on StreamPluginService's <=0 default (200) instead of sentinel values
- Validate any status forwarded from upstream services before mapping it into a plugin service response
When it happens
Trigger: StreamPluginService(mode, status, serve) is called with a status < 100 or > 999; a Response[PluginServiceContent] carries an out-of-range httpStatus when the endpoint computes pluginServiceStatus; ValidatePluginServiceResponse is invoked with a bad status during bundle response validation.
Common situations: Passing an error-sentinel status like -1 or 0 from application code that assumed the library would substitute a default (only 0/negative is normalized, but custom paths may bypass), computing a status arithmetically (e.g. 200+extra*1000), or forwarding an upstream status code larger than 999.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Field [ ] is required
- Field [ ] must not be empty
- HTTP
- invalid AI provider HTTP headers
- invalid request:
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/1fe23e789a2b3f9e.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/apicontract/plugin_service_protocol.go:135
func validatePluginServiceDefinition(definition Definition) error {
if (definition.Output == PluginServiceOutput) != (definition.PluginService != nil) {
return fmt.Errorf("plugin service output requires a protocol declaration")
}
if definition.PluginService == nil {
return nil
}
if definition.Data != reflect.TypeFor[PluginServiceContent]() || definition.SSE != nil || definition.Proxy != nil || definition.WebSocket != nil || definition.DataOnError || definition.ErrorStatus != 0 {
return fmt.Errorf("invalid plugin service response options")
}
if !reflect.DeepEqual(definition.PluginService, PluginServiceOptions().PluginService) {
return fmt.Errorf("invalid plugin service protocol variants")
}
return nil
}
func validatePluginServiceStatus(mode PluginServiceMode, status int) error {
if status < 100 || status > 999 {
return fmt.Errorf("invalid plugin service HTTP status: %d", status)
}
known := false
for _, variant := range PluginServiceOptions().PluginService.Variants {
if variant.Mode == mode {
known = true
break
}
}
if !known {
return fmt.Errorf("unknown plugin service mode: %s", mode)
}
switch mode {
case PluginServiceAdmission:
if status != 400 && status != 404 && status != 500 && status != 503 {
return fmt.Errorf("undeclared plugin admission status")
}
case PluginServiceRedirect:
if status != 201 && (status < 300 || status > 308) {View on GitHub (pinned to 9f775e8a12)