siyuan-note/siyuan · error · ErrPluginPublishInvalid

invalid plugin publish declaration or data

Error message

invalid plugin publish declaration or data

What it means

ErrPluginPublishInvalid is thrown when a plugin's publish declaration in plugin.json or its persisted publish data fails validation: manifest >1 MiB, unparseable JSON, manifest.Name mismatch, missing/invalid publish declaration, resource or data field counts over limits (4096/128), undeclared-safe relative paths, reserved files (plugin.json/kernel.js), or data field names outside [A-Za-z0-9_-] or longer than 128 chars. The API layer maps it to HTTP 400 Bad Request.

Solutions

  1. Fix plugins/<name>/plugin.json: make Name match the package, keep publish.resources as exact relative file paths, cap at 4096 resources / 128 data fields
  2. Rename data fields to only [A-Za-z0-9_-] and at most 128 characters
  3. Ensure the file is valid JSON under 1 MiB
  4. Delete the corrupt publish state file for the plugin so it is regenerated, then re-grant and re-save data
  5. Never list plugin.json or kernel.js in resources — they are implicitly forbidden

Example fix

// before (invalid: directory + reserved file)
"publish": { "resources": ["assets/", "plugin.json"], "data": ["my field"] }
// after (valid: exact files, safe field name)
"publish": { "resources": ["assets/logo.png"], "data": ["my_field"] }
Defensive patterns

Strategy: validation

Validate before calling

function validatePublish(manifest, pkgName) {
  if (manifest.name !== pkgName) return "manifest.Name must match package name";
  const p = manifest.publish || {resources: [], data: []};
  if (p.resources.length > 4096 || p.data.length > 128) return "limit exceeded";
  for (const r of p.resources) {
    if (r.includes("..") || r.startsWith("/") || /^(plugin|kernel)\.json$/i.test(r)) return "bad resource: " + r;
  }
  for (const f of p.data) {
    if (!/^[A-Za-z0-9_-]{1,128}$/.test(f)) return "bad data field: " + f;
  }
  return null;
}

Prevention

When it happens

Trigger: pluginPublishDeclaration reading a plugin.json over 1 MiB or with a Name not matching the directory; declaring >4096 resources or >128 data fields; a resource path failing util.IsPublishRelativePath or equal (case-insensitive) to plugin.json/kernel.js; data field names with illegal characters; readPluginPublishState/SetPluginPublishDataGrant/SavePluginPublishData encountering corrupt state JSON.

Common situations: Hand-edited plugin.json with typo'd publish arrays; wildcard or directory entries in publish.resources (not supported); renaming the plugin directory without updating manifest.Name; corrupted publish state file after a crash or manual edit; data fields created programmatically with spaces or slashes in names.

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/3143cb915265bcd2. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/plugin_publish.go:23

	"encoding/json"
	"errors"
	"io"
	"os"
	"path/filepath"
	"slices"
	"strings"
	"sync"

	"github.com/88250/gulu"
	"github.com/gin-gonic/gin"
	"github.com/siyuan-note/siyuan/kernel/bazaar"
	"github.com/siyuan-note/siyuan/kernel/util"
)

var (
	ErrPluginPublishDenied  = errors.New("plugin publish access denied")
	ErrPluginPublishMissing = errors.New("plugin publish data has not been generated")
	ErrPluginPublishInvalid = errors.New("invalid plugin publish declaration or data")
	pluginPublishLock       sync.Mutex
)

// PluginPublishDeclaration 的资源为精确文件名,数据为可公开的顶层标量字段,不支持目录或通配符。
type PluginPublishDeclaration struct {
	Resources []string `json:"resources"`
	Data      []string `json:"data"`
}

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

type pluginPublishState struct {
	Version int                        `json:"version"`
	Granted []string                   `json:"granted"`

View on GitHub (pinned to 9f775e8a12)