{"record":{"id":"c39e0553c2f86bba","repo":"siyuan-note/siyuan","slug":"unsupported-enum-field-s","errorCode":null,"errorMessage":"unsupported enum field: %s","messagePattern":"unsupported enum field: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/apicontract/decode.go","lineNumber":126,"sourceCode":"\t\t\tdecodeErr = decodeRequestValue(raw, value.Field(i))\n\t\t}\n\t\tif decodeErr != nil {\n\t\t\tif has(\"ignoretype\") {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn fmt.Errorf(\"Field [%s] has an invalid type: %w\", name, decodeErr)\n\t\t}\n\t\tif has(\"trim\") {\n\t\t\ttrimmed := strings.TrimSpace(value.Field(i).String())\n\t\t\tif trimmed == \"\" {\n\t\t\t\treturn fmt.Errorf(\"Field [%s] must not be empty\", name)\n\t\t\t}\n\t\t\tvalue.Field(i).SetString(trimmed)\n\t\t}\n\t\tfor _, option := range strings.Split(field.Tag.Get(\"api\"), \",\") {\n\t\t\tif strings.HasPrefix(option, \"enum=\") {\n\t\t\t\tif field.Type.Kind() != reflect.String {\n\t\t\t\t\treturn fmt.Errorf(\"unsupported enum field: %s\", name)\n\t\t\t\t}\n\t\t\t\tfound := false\n\t\t\t\tfor _, choice := range strings.Split(strings.TrimPrefix(option, \"enum=\"), \"|\") {\n\t\t\t\t\tif value.Field(i).String() == choice {\n\t\t\t\t\t\tfound = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif !found {\n\t\t\t\t\treturn fmt.Errorf(\"Field [%s] has an invalid value\", name)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif strings.HasPrefix(option, \"const=\") {\n\t\t\t\tvar expected, actual any\n\t\t\t\tif err := json.Unmarshal([]byte(strings.TrimPrefix(option, \"const=\")), &expected); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tdata, err := json.Marshal(value.Field(i).Interface())","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/apicontract/decode.go#L108-L144","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\ntype Req struct { Level int `json:\"level\" api:\"enum=1|2|3\"` }\n// after\ntype Req struct { Level string `json:\"level\" api:\"enum=1|2|3\"` }","handlingStrategy":"validation","validationCode":"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 }","typeGuard":"null","tryCatchPattern":"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 }","preventionTips":["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"],"tags":["enum","api-contract","reflection","schema"],"backgroundTag":"unsupported-enum-value","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}