siyuan-note/siyuan · error
Field [ ] must not be empty
Error message
Field [%s] must not be empty
What it means
SiYuan kernel API contract layer rejects AI request fields marked as required-and-trimmed when, after whitespace trimming, the string value is empty. aiLegacyString first decodes the field as a String via legacyField, then applies strings.TrimSpace and fails with 'Field [<key>] must not be empty'. This guards endpoints like /api/ai/chatGPT from receiving blank prompt payloads.
Solutions
- Ensure the AI message field contains a non-empty, non-whitespace string before calling the endpoint
- Trim or reject empty input on the client side before sending
- If the field is genuinely optional in your flow, check whether the endpoint/field is marked optional; otherwise supply a placeholder value
Example fix
// before
fetchPost("/api/ai/chatGPT", {msg: userText});
// after
const msg = (userText ?? "").trim();
if (!msg) throw new Error("msg is required");
fetchPost("/api/ai/chatGPT", {msg}); Defensive patterns
Strategy: validation
Validate before calling
function assertNonEmpty(v, name) { const s = (v ?? "").trim(); if (!s) throw new Error(`Field [${name}] must not be empty`); return s; }
const msg = assertNonEmpty(userText, "msg"); Type guard
const isNonEmptyString = (v) => typeof v === "string" && v.trim().length > 0;
Try / catch
try { const data = await post("/api/ai/chatGPT", {msg}); } catch (e) { if (/must not be empty/.test(e.message)) { /* prompt user for input */ } else throw e; } Prevention
- Trim and check user-supplied text before every AI API call
- Bind UI inputs with required + minlength validation
- Never interpolate possibly-undefined variables into request fields without a default
When it happens
Trigger: POSTing to the AI chat endpoint with the 'msg' field set to "", " ", "\n\t" or omitting it entirely when it is required (e.g. /api/ai/chatGPT with {"msg": " "}).
Common situations: Bots or scripts that concatenate user input without checking it, prompt templates whose variable substitution produced empty strings, form/textarea bindings that submit whitespace, or clients sending null/missing fields to legacy field-based endpoints.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- Field [ ] must not be empty
- AI editor action must not be empty
- AI editor input is empty
- asset data is empty
- at least one asset path or mapping is required
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/afa1442512304c78.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/apicontract/ai_input.go:33
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
}
func aiJSONDecoder[Request, Data any](endpoint *Endpoint[Request, Data], bind func(fileTreeFields) (Request, error)) {
endpoint.decodeRequest = func(reader io.Reader) (value Request, err error) {
fields, err := fileTreeRequestFields(reader, endpoint.definition.Path)
if err == nil {
value, err = bind(fields)
}
return
}
}
func aiProviderFields(fields fileTreeFields) AIProviderRequest {
request := AIProviderRequest{}
_ = json.Unmarshal(fields["provider"], &request.Provider)View on GitHub (pinned to 9f775e8a12)