{"record":{"id":"d2f1f8e78d8bbc7f","repo":"siyuan-note/siyuan","slug":"unregistered-plugin-service-s-s","errorCode":null,"errorMessage":"unregistered plugin service: %s %s","messagePattern":"unregistered plugin service: (.+?) (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/apicontract/plugin_service_protocol.go","lineNumber":191,"sourceCode":"\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}\n\t}\n\tif !found {\n\t\treturn fmt.Errorf(\"unregistered plugin service: %s %s\", method, path)\n\t}\n\tif err := validatePluginServiceStatus(mode, status); err != nil {\n\t\treturn err\n\t}\n\tif 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\tswitch mode {\n\tcase PluginServiceEmpty:\n\t\tif len(payload) != 0 {\n\t\t\treturn fmt.Errorf(\"empty plugin response contains a body\")\n\t\t}\n\tcase PluginServiceJSON, PluginServiceASCIIJSON, PluginServiceIndentedJSON, PluginServicePureJSON:\n\t\tif !json.Valid(payload) {\n\t\t\treturn fmt.Errorf(\"invalid plugin JSON response\")","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/apicontract/plugin_service_protocol.go#L173-L209","documentation":"ValidatePluginServiceResponse looks up the bundle's registered endpoints for one whose method and path match and that declares a PluginService schema. This error means no such plugin-service endpoint is registered, so the response cannot be validated against any contract definition.","triggerScenarios":"Calling Bundle.ValidatePluginServiceResponse(\"GET\", \"/plugins/foo/bar\", ...) where /plugins/foo/bar is not in b.Endpoints, the method differs (POST vs GET), or the endpoint exists but has no PluginService declaration (validatePluginServiceDefinition failed).","commonSituations":"Route typos or missing leading/trailing slashes; registering the endpoint under a different HTTP method; forgetting to declare the pluginService output when building the endpoint schema; a stale bundle built before the endpoint was added.","solutions":["Verify the exact method and path string against the registered endpoint definitions","Ensure the endpoint schema declares Output: PluginServiceOutput with PluginServiceOptions() so PluginService is non-nil","Rebuild/refresh the Bundle so it contains the newly added plugin-service endpoint"],"exampleFix":"// before\nbundle.ValidatePluginServiceResponse(\"POST\", \"/plugins/demo/data\", ...)\n// after\nbundle.ValidatePluginServiceResponse(\"GET\", \"/plugins/demo/data\", ...) // matches registration","handlingStrategy":"validation","validationCode":"registered := false\nfor _, ep := range bundle.Endpoints {\n\tif ep.Method == method && ep.Path == path && ep.PluginService != nil {\n\t\tregistered = true\n\t\tbreak\n\t}\n}\nif !registered {\n\treturn fmt.Errorf(\"endpoint %s %s is not a registered plugin service\", method, path)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep method/path constants in one place shared by registration and validation","Confirm the endpoint schema sets Output: PluginServiceOutput with PluginServiceOptions()","Rebuild the Bundle after adding endpoints before running response validation"],"tags":["go","api-contract","plugin-service","routing"],"backgroundTag":"resource-not-found","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"}