siyuan-note/siyuan · error
Field [ ] must not be empty
Error message
Field [%s] must not be empty
What it means
When decoding getBazaarPackageRatings/getBazaarPackageUserRatings requests, each packageNames element is unmarshaled into a string; JSON null or a non-string element (number, object, bool) causes the decoder to record this error on the request instead of failing outright, preserving legacy response behavior. It signals the packageNames array is present but not an array of strings.
Solutions
- Send only string elements in packageNames, e.g. ["siyuan-plugin-a","siyuan-plugin-b"]
- Filter out null/undefined values before serializing the array on the client
- Check request.NamesError / the API error response to see the decode result
- Validate the payload shape against the generated API contract schema
Example fix
// before
fetchPost('/api/bazaar/getBazaarPackageRatings', {packageType: 'plugins', packageNames: [null, 'x']})
// after
fetchPost('/api/bazaar/getBazaarPackageRatings', {packageType: 'plugins', packageNames: ['x']}) Defensive patterns
Strategy: validation
Validate before calling
function validatePackageNames(names) {
return Array.isArray(names) && names.every(n => typeof n === 'string') && names.length > 0;
}
// call before the API
if (!validatePackageNames(packageNames)) throw new Error('packageNames must be a non-empty array of strings'); Type guard
const isStringArray = (v) => Array.isArray(v) && v.every(n => typeof n === 'string');
Try / catch
try {
await fetchPost('/api/bazaar/getBazaarPackageRatings', {packageType, packageNames: names.filter(n => typeof n === 'string')});
} catch (e) {
console.error('invalid packageNames payload:', e.message);
} Prevention
- Filter null/undefined/non-strings out of packageNames before serialization
- Type-check request builders so packageNames is string[] end to end
- Validate payloads against the generated API contract schema in tests
When it happens
Trigger: Calling /api/bazaar/getBazaarPackageRatings or getBazaarPackageUserRatings with packageNames containing null, a number (e.g. [1,2]), nested objects, or booleans.
Common situations: Client code builds the array from mixed-type data; a null slips in from an undefined variable serialized by JSON.stringify; external API consumers guess the schema.
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
- element [ ]
- empty JSON value
- entry [ ]
- Field [conf] should be of type [Object]
- Field [ ] has an invalid constant
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/7de3fe8078042be3.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/apicontract/bazaar.go:464
s, err := b.schema(member, input)
if err != nil {
return nil, err
}
variants = append(variants, s)
}
b.definitions[t.Name()] = &Schema{AnyOf: variants}
return &Schema{Ref: "#/$defs/" + t.Name()}, nil
}
func bazaarString(fields map[string]json.RawMessage, key string, required, trim bool) (string, error) {
value, err := legacyField[string](fields, key, "String", required)
if err != nil {
return "", err
}
if trim && len(fields[key]) > 0 && string(fields[key]) != "null" {
value = strings.TrimSpace(value)
if value == "" {
return "", fmt.Errorf("Field [%s] must not be empty", key)
}
}
return value, nil
}
func init() {
InstallLocalBazaarPackage.decodeFailure = func(err error) Response[BazaarLocalInstallResult] {
return Failure[BazaarLocalInstallResult](1, "Marketplace package file is required")
}
BatchUpdatePackage.decodeRequest = func(reader io.Reader) (request BatchUpdatePackageRequest, err error) {
fields, err := bazaarRequestFields(reader, "/api/bazaar/batchUpdatePackage")
if err != nil {
return request, err
}
if request.Frontend, err = bazaarString(fields, "frontend", true, true); err != nil {
return request, err
}
return request, nil
}View on GitHub (pinned to 9f775e8a12)