{"record":{"id":"529b41d9d54bfa07","repo":"siyuan-note/siyuan","slug":"invalid-plugin-service-http-status","errorCode":null,"errorMessage":"invalid plugin service HTTP status","messagePattern":"invalid plugin service HTTP status","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/apicontract/plugin_service_protocol.go","lineNumber":170,"sourceCode":"\tcase PluginServiceRedirect:\n\t\tif status != 201 && (status < 300 || status > 308) {\n\t\t\treturn fmt.Errorf(\"invalid plugin redirect status\")\n\t\t}\n\tcase PluginServiceWebSocket:\n\t\tif status != 101 && status != 400 && status != 500 {\n\t\t\treturn fmt.Errorf(\"invalid plugin WebSocket status\")\n\t\t}\n\tcase PluginServiceSSE:\n\t\tif status != 200 && status != 500 {\n\t\t\treturn fmt.Errorf(\"invalid plugin SSE status\")\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (b *Bundle) validatePluginServiceHTTPResponse(endpoint EndpointSchema, status int, contentType string, payload []byte) error {\n\tif status < 100 || status > 999 {\n\t\treturn fmt.Errorf(\"invalid plugin service HTTP status\")\n\t}\n\tif endpoint.Method == \"HEAD\" || status < 200 || status == 204 || status == 304 {\n\t\tif len(payload) > 0 {\n\t\t\treturn fmt.Errorf(\"plugin service response forbids a body\")\n\t\t}\n\t\treturn nil\n\t}\n\t// 原始文件、代理及插件自选媒体允许任意字节，具体分支由 ValidatePluginServiceResponse 校验。\n\treturn nil\n}\n\nfunc (b *Bundle) ValidatePluginServiceResponse(method, path string, mode PluginServiceMode, status int, contentType string, payload []byte) error {\n\tvar found bool\n\tfor _, endpoint := range b.Endpoints {\n\t\tif endpoint.Method == method && endpoint.Path == path && endpoint.PluginService != nil {\n\t\t\tfound = true\n\t\t\tbreak\n\t\t}","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/apicontract/plugin_service_protocol.go#L152-L188","documentation":"validatePluginServiceHTTPResponse first sanity-checks the status code as a valid HTTP code (100-999) before applying body rules. This error means a status outside 100-999 (0, negative, or >999) was passed while validating a plugin-service HTTP response, so the value cannot be an HTTP status at all.","triggerScenarios":"Calling Bundle.ValidateHTTPResponse for a plugin-service endpoint with status 0 (unset), a negative value, or a number above 999, typically when the status variable was never assigned or carries a custom non-HTTP code.","commonSituations":"Forgetting to set the response status so the zero value 0 is validated; passing an application-specific error code instead of an HTTP status; integer overflow or sign errors when computing the status.","solutions":["Initialize the status to a valid HTTP code (e.g. 200) before validation","Check where the status is computed; replace custom codes with standard HTTP status codes","Guard with `if status < 100 || status > 999 { status = http.StatusInternalServerError }` before calling validation"],"exampleFix":"// before\nstatus := 0\nbundle.ValidateHTTPResponse(endpoint, status, ct, payload)\n// after\nstatus := http.StatusOK\nbundle.ValidateHTTPResponse(endpoint, status, ct, payload)","handlingStrategy":"validation","validationCode":"func validHTTPStatus(status int) bool {\n\treturn status >= 100 && status <= 999\n}\nif !validHTTPStatus(status) {\n\tstatus = http.StatusInternalServerError\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never validate a zero-value status; initialize to a sane default first","Map internal error codes to standard net/http statuses before validation","Add a boundary test for status 0 and 1000 in response-validation tests"],"tags":["go","api-contract","http-status","validation"],"backgroundTag":"value-out-of-range","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}