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
- 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
- Rename data fields to only [A-Za-z0-9_-] and at most 128 characters
- Ensure the file is valid JSON under 1 MiB
- Delete the corrupt publish state file for the plugin so it is regenerated, then re-grant and re-save data
- 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
- Validate plugin.json publish declaration in CI before releasing the plugin
- Never use directories, wildcards, or reserved file names in publish.resources
- Keep data field names to [A-Za-z0-9_-] and <=128 chars
- Keep plugin.json under 1 MiB and confirm Name equals the package directory name
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
- cannot remove storage root
- config.actionEffects contains an empty action
- createDocTree document contains unknown field
- each key must be an object
- failed to serialize inputSchema
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)