siyuan-note/siyuan · error
invalid request
Error message
invalid request: %s
What it means
AIProviderRequest's request binding decodes the incoming JSON body into a Request value; when json.Decode fails, the raw decoder error is rewritten (renaming internal struct names back to legacy field names) and wrapped as 'invalid request: %s'. It means the request body sent to the AI API does not match the expected schema.
Solutions
- Inspect the wrapped message after 'invalid request: ' — it names the exact JSON decode problem
- Validate the payload against the Request schema before sending
- Send Content-Type: application/json with a syntactically valid JSON body
- Update the plugin/client to the current AI request format
Example fix
// before
fetch(url, {body: "prompt=hi"}) // form-encoded
// after
fetch(url, {
headers: {"Content-Type": "application/json"},
body: JSON.stringify({prompt: "hi"})
}) Defensive patterns
Strategy: try-catch
Validate before calling
try { JSON.parse(payload); } catch (e) { throw new Error("body is not valid JSON"); } Try / catch
try {
await fetchPost("/api/ai/...", payload);
} catch (e) {
if (String(e).includes("invalid request:")) {
console.error("Schema mismatch:", e.message); // details follow the prefix
}
} Prevention
- Always send Content-Type: application/json
- JSON.stringify the payload; never hand-build JSON strings
- Validate field types against the Request schema before sending
- Keep plugins updated to the current AI request format
When it happens
Trigger: POSTing a body to the AI input endpoint that is not valid JSON or does not unmarshal into the Request struct: wrong field types, unknown malformed payload, trailing garbage, or truncated JSON.
Common situations: Client sends form-encoded data instead of JSON; a field typed as string receives a number; plugin uses an outdated request shape; body got truncated by a proxy.
Related errors
- element [ ]
- empty JSON value
- entry [ ]
- Field [conf] should be of type [Object]
- Field [ ] has an invalid constant
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/1878cad43b0f8fa0.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/apicontract/ai_input.go:20
import (
"bytes"
"encoding/json"
"fmt"
"io"
"reflect"
"strings"
)
func aiStructDecoder[Request, Data any](endpoint *Endpoint[Request, Data], legacyName string) {
endpoint.decodeRequest = func(reader io.Reader) (value Request, err error) {
err = json.NewDecoder(reader).Decode(&value)
if err != nil {
message := strings.ReplaceAll(err.Error(), reflect.TypeFor[Request]().Name()+".", legacyName+".")
for _, name := range []string{"Reference", "EditorContext", "FrontendCapability", "ToolEffects"} {
message = strings.ReplaceAll(message, "AI"+name+".", name+".")
}
err = fmt.Errorf("invalid request: %s", message)
}
return
}
}
func (r AIProviderRequest) ProviderError() error { return r.providerError }
func aiLegacyString(fields fileTreeFields, key string, required, trim bool) (value string, err error) {
value, err = legacyField[string](fields, key, "String", required)
if err == nil && trim {
value = strings.TrimSpace(value)
if value == "" {
err = fmt.Errorf("Field [%s] must not be empty", key)
}
}
return
}
View on GitHub (pinned to 9f775e8a12)