siyuan-note/siyuan · error

Field [conf] is required

Error message

Field [conf] is required

What it means

GraphConfiguration is a lazy-binding wrapper for graph config; its UnmarshalJSON rejects JSON null because an 'Object' conf is mandatory for graph endpoints. Null would erase defaults/merge order, so it raises 'Field [conf] is required'. If the data is present but not an object, a separate 'should be of type [Object]' error is returned.

Solutions

  1. Send a JSON object for conf, e.g. {} to accept defaults, instead of null
  2. If resetting settings, pass an empty object rather than null
  3. Check upstream serialization so conf is omitted from the reset path or defaulted to {}

Example fix

// before
fetchPost("/api/graph/getGraph", { id: "nb", conf: null });
// after
fetchPost("/api/graph/getGraph", { id: "nb", conf: {} });
Defensive patterns

Strategy: validation

Validate before calling

if (conf === null || conf === undefined) conf = {};
if (typeof conf !== "object" || Array.isArray(conf)) throw new TypeError("conf must be a plain object");

Type guard

const hasConf = (b) => b.conf !== null && b.conf !== undefined && typeof b.conf === "object" && !Array.isArray(b.conf);

Try / catch

try {
  await fetchPost("/api/graph/getGraph", { id, conf });
} catch (e) {
  if (String(e.message).includes("[conf] is required")) {
    await fetchPost("/api/graph/getGraph", { id, conf: {} });
  }
}

Prevention

When it happens

Trigger: Calling a graph API (e.g. getGraph or local graph config) with {"conf":null} or a body whose conf key decodes to null.

Common situations: Clients clearing graph settings by sending null instead of an empty object; refactored code where conf became optional; serialized config where conf was dropped and null-substituted.

Related errors


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

Appendix: source

Thrown at kernel/apicontract/graph_input.go:16

package apicontract

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"strings"
)

// GraphConfiguration 延迟绑定具体图配置,使局部图继续忽略全局图字段,并保留默认值合并顺序。
type GraphConfiguration struct{ raw json.RawMessage }

func (c *GraphConfiguration) UnmarshalJSON(data []byte) error {
	if bytes.Equal(bytes.TrimSpace(data), []byte("null")) {
		return fmt.Errorf("Field [conf] is required")
	}
	fields, err := legacyJSONValue[map[string]json.RawMessage](data)
	if err != nil {
		return fmt.Errorf("Field [conf] should be of type [Object]")
	}
	c.raw, err = json.Marshal(fields)
	return err
}

func (c GraphConfiguration) MarshalJSON() ([]byte, error) {
	if len(c.raw) == 0 {
		return []byte("{}"), nil
	}
	return c.raw, nil
}

type GraphConfigurationFields struct {
	MinRefs   *int             `json:"minRefs" api:"optional"`

View on GitHub (pinned to 9f775e8a12)