siyuan-note/siyuan · error

published data fields must be JSON scalars

Error message

published data fields must be JSON scalars

What it means

PublishDataValue is a JSON value type used by the plugin publish request to ensure each published data field is a JSON scalar (string, number, boolean, null). UnmarshalJSON rejects empty/invalid JSON as well as any value starting with '{' or '[' — i.e. objects and arrays — to keep published data flat and scalar-only.

Solutions

  1. Flatten the published data so every field value is a scalar (string, number, boolean, or null).
  2. Serialize nested structures to a JSON string inside a scalar field if structure must be preserved.
  3. Validate the payload with json.Valid plus a scalar check before sending.

Example fix

// before
{"data": {"meta": {"version": 1}}}
// after
{"data": {"meta": "{\"version\":1}"}}
Defensive patterns

Strategy: validation

Validate before calling

function dataFieldsAreScalars(data) {
  return Object.values(data).every(v => v === null || ["string", "number", "boolean"].includes(typeof v));
}

Type guard

const isScalar = (v) => v === null || ["string", "number", "boolean"].includes(typeof v);

Try / catch

try { await publish({data}); } catch (e) { if (String(e).includes("must be JSON scalars")) { throw new Error("flatten data fields before publishing: " + e.message); } throw e; }

Prevention

When it happens

Trigger: Unmarshalling a plugin publish request whose data object contains a field whose value is a JSON object or array (e.g. {"data": {"key": {"nested": 1}}} or {"key": [1,2]}).

Common situations: A plugin publishes structured/nested metadata instead of flat scalar key-values; a client reuses a generic config object as the data payload; schema drift after adding nested fields.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at kernel/apicontract/plugin_publish.go:21

import (
	"bytes"
	"encoding/json"
	"errors"
)

// PublishDataValue 限定公开字段为标量,避免嵌套对象扩展绕过字段授权。
type PublishDataValue struct{ raw json.RawMessage }

func (v PublishDataValue) MarshalJSON() ([]byte, error) {
	if len(v.raw) == 0 {
		return []byte("null"), nil
	}
	return v.raw, nil
}
func (v *PublishDataValue) UnmarshalJSON(data []byte) error {
	data = bytes.TrimSpace(data)
	if !json.Valid(data) || data[0] == '{' || data[0] == '[' {
		return errors.New("published data fields must be JSON scalars")
	}
	v.raw = append(v.raw[:0], data...)
	return nil
}

type PluginPublishRequest struct {
	PackageName string `json:"packageName"`
}

type PluginPublishInfo struct {
	Resources []string `json:"resources" api:"nonnullable"`
	Fields    []string `json:"fields" api:"nonnullable"`
	Granted   bool     `json:"granted"`
}

type SetPluginPublishDataGrantRequest struct {
	PackageName string   `json:"packageName"`
	Fields      []string `json:"fields"`

View on GitHub (pinned to 9f775e8a12)