siyuan-note/siyuan · error
unsupported enum field
Error message
unsupported enum field: %s
What it means
A field carrying an `enum=a|b|c` api option must be of string kind; if the contract author applies enum to a non-string field (int, bool, struct), decodeRequestFields returns this error before any value checking. It is a contract-definition mistake surfaced at request time.
Solutions
- Change the contract field to type string, or express the enum via `const=` options per accepted value
- Use a plain string field with enum for textual enums
- Add a unit test decoding a sample request for every contract to catch kind mismatches early
Example fix
// before
type Req struct { Level int `json:"level" api:"enum=1|2|3"` }
// after
type Req struct { Level string `json:"level" api:"enum=1|2|3"` } Defensive patterns
Strategy: validation
Validate before calling
func validateEnumKinds(t reflect.Type) error { for i := 0; i < t.NumField(); i++ { f := t.Field(i); if strings.Contains(f.Tag.Get("api"), "enum=") && f.Type.Kind() != reflect.String { return fmt.Errorf("enum field %s must be string kind", f.Name) } }; return nil } Type guard
null
Try / catch
if err := decodeRequestFields(value, fields); err != nil { if strings.HasPrefix(err.Error(), "unsupported enum field") { return fmt.Errorf("contract bug: enum tag on non-string field: %w", err) }; return err } Prevention
- Only apply enum= tags to string fields
- Use const= options for non-string fixed values
- Add contract decode unit tests so kind mismatches surface in CI, not at request time
When it happens
Trigger: Declaring `api:"enum=1|2|3"` on an int field, or enum on a custom string-like type that reflection sees as non-string kind, then processing a request for that contract.
Common situations: Copy-pasting enum tags from string fields onto numeric fields; using named non-string types (type Mode int) with enum tags; code-generated contracts adding enum to wrong fields.
Related errors
- unsupported embedded request field
- Field [ ] has an invalid value
- request contract must be a struct
- attribute view embedded base is missing
- catalog has no providers with API endpoints and valid models
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/c39e0553c2f86bba.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/apicontract/decode.go:126
decodeErr = decodeRequestValue(raw, value.Field(i))
}
if decodeErr != nil {
if has("ignoretype") {
continue
}
return fmt.Errorf("Field [%s] has an invalid type: %w", name, decodeErr)
}
if has("trim") {
trimmed := strings.TrimSpace(value.Field(i).String())
if trimmed == "" {
return fmt.Errorf("Field [%s] must not be empty", name)
}
value.Field(i).SetString(trimmed)
}
for _, option := range strings.Split(field.Tag.Get("api"), ",") {
if strings.HasPrefix(option, "enum=") {
if field.Type.Kind() != reflect.String {
return fmt.Errorf("unsupported enum field: %s", name)
}
found := false
for _, choice := range strings.Split(strings.TrimPrefix(option, "enum="), "|") {
if value.Field(i).String() == choice {
found = true
break
}
}
if !found {
return fmt.Errorf("Field [%s] has an invalid value", name)
}
}
if strings.HasPrefix(option, "const=") {
var expected, actual any
if err := json.Unmarshal([]byte(strings.TrimPrefix(option, "const=")), &expected); err != nil {
return err
}
data, err := json.Marshal(value.Field(i).Interface())View on GitHub (pinned to 9f775e8a12)