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
- Flatten the published data so every field value is a scalar (string, number, boolean, or null).
- Serialize nested structures to a JSON string inside a scalar field if structure must be preserved.
- 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
- Keep published plugin data flat: scalar values only.
- JSON.stringify nested objects into a string field when structure is needed.
- Add a payload unit test that validates each data field type before release.
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
- builtin color must not be null
- builtin style must not be null
- cannot remove storage root
- Conf.Language(317)
- config.actionEffects contains an empty action
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)