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

  1. Ensure the AI message field contains a non-empty, non-whitespace string before calling the endpoint
  2. Trim or reject empty input on the client side before sending
  3. 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

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


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)