siyuan-note/siyuan · error

Field [conf] is required

Error message

Field [conf] is required

What it means

decodeGraphConfiguration decodes the `conf` entry of an incoming fields map into a GraphConfiguration value. When the `conf` key is absent or null (zero-length raw bytes) it returns 'Field [conf] is required'. This is the query-side mirror of the write-path validation, ensuring graph queries that return configuration always carry a conf object.

Solutions

  1. Include "conf": {} (or the actual configuration object) in the query payload
  2. Replace "conf": null with a concrete object
  3. Inspect the request body actually sent (log it) — a serialization bug may drop empty objects

Example fix

// before
{"id": "local"}
// after
{"id": "local", "conf": {}}
Defensive patterns

Strategy: validation

Validate before calling

if (payload.conf == null) {
  payload.conf = {}; // ensure query payloads always carry conf
}

Type guard

const hasConfField = (b) => Object.prototype.hasOwnProperty.call(b, "conf") && b.conf !== null;

Prevention

When it happens

Trigger: A graph query request (decoded in graph_query.go) whose payload omits `conf` or sets it to null; decodeGraphConfiguration is invoked from the anonymous request-decoding function for query endpoints.

Common situations: Query clients sending only identifiers (like `id`) and forgetting that configuration is also required; template-based requests where the conf section was deleted.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/58bf2b3155d72e9f. Report an issue: GitHub.

Appendix: source

Thrown at kernel/apicontract/graph_query.go:114

func (e *graphQueryDecodeError) Error() string { return e.cause.Error() }

func graphQueryFields(reader io.Reader, path string) (map[string]json.RawMessage, JSONValue, error) {
	fields, err := blockRequestFields(reader, path)
	var reqID JSONValue
	if err != nil {
		return nil, reqID, err
	}
	if raw, exists := fields["reqId"]; exists {
		if err = json.Unmarshal(raw, &reqID); err != nil {
			return nil, reqID, err
		}
	}
	return fields, reqID, nil
}

func decodeGraphConfiguration(fields map[string]json.RawMessage) (value GraphConfiguration, err error) {
	if len(fields["conf"]) == 0 {
		return value, fmt.Errorf("Field [conf] is required")
	}
	err = json.Unmarshal(fields["conf"], &value)
	return
}

func init() {
	GetGraph.decodeRequest = func(reader io.Reader) (request GlobalGraphRequest, err error) {
		fields, reqID, err := graphQueryFields(reader, "/api/graph/getGraph")
		if err != nil {
			return request, err
		}
		request.ReqID = reqID
		defer func() {
			if err != nil {
				err = &graphQueryDecodeError{reqID, err}
			}
		}()
		if request.K, err = legacyField[string](fields, "k", "String", false); err != nil {

View on GitHub (pinned to 9f775e8a12)