{"record":{"id":"f4a2887c7f48583a","repo":"siyuan-note/siyuan","slug":"field-s-must-not-be-empty-av-decode","errorCode":null,"errorMessage":"Field [%s] must not be empty","messagePattern":"Field \\[(.+?)\\] must not be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/apicontract/av_decode.go","lineNumber":144,"sourceCode":"func avDecodeParsedRequest[Request any](reader io.Reader, path string) (request Request, err error) {\n\tfields, err := blockRequestFields(reader, path)\n\tif err != nil {\n\t\treturn request, err\n\t}\n\tvalue := reflect.ValueOf(&request).Elem()\n\tfor i := 0; i < value.NumField(); i++ {\n\t\tfield := value.Type().Field(i)\n\t\tname := field.Tag.Get(\"json\")\n\t\toptions := \",\" + field.Tag.Get(\"api\") + \",\"\n\t\trequired := !strings.Contains(options, \",optional,\")\n\t\tswitch field.Type.Kind() {\n\t\tcase reflect.String:\n\t\t\tvar decoded string\n\t\t\tdecoded, err = legacyField[string](fields, name, \"String\", required)\n\t\t\tif err == nil && strings.Contains(options, \",trim,\") {\n\t\t\t\tdecoded = strings.TrimSpace(decoded)\n\t\t\t\tif decoded == \"\" {\n\t\t\t\t\terr = fmt.Errorf(\"Field [%s] must not be empty\", name)\n\t\t\t\t}\n\t\t\t}\n\t\t\tvalue.Field(i).SetString(decoded)\n\t\tcase reflect.Bool:\n\t\t\tvar decoded bool\n\t\t\tdecoded, err = legacyField[bool](fields, name, \"Boolean\", required)\n\t\t\tvalue.Field(i).SetBool(decoded)\n\t\tcase reflect.Float64:\n\t\t\tvar decoded float64\n\t\t\tdecoded, err = legacyField[float64](fields, name, \"Number\", required)\n\t\t\tvalue.Field(i).SetFloat(decoded)\n\t\tcase reflect.Slice:\n\t\t\tvar entries []json.RawMessage\n\t\t\tentries, err = legacyField[[]json.RawMessage](fields, name, \"Array\", required)\n\t\t\tvar decoded []string\n\t\t\tfor _, entry := range entries {\n\t\t\t\tvar item string\n\t\t\t\tif !bytes.Equal(entry, []byte(\"null\")) && json.Unmarshal(entry, &item) == nil {","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/apicontract/av_decode.go#L126-L162","documentation":"avDecodeParsedRequest walks request struct fields reflectively; for string-kind fields tagged with the ,trim, api option, the decoded value is trimmed and an all-whitespace/empty value fails with 'Field [<name>] must not be empty'. Used by endpoints like getAttributeViewPasteRows and createAttributeViewItem variants.","triggerScenarios":"Calling /api/av/getAttributeViewPasteRows, getAttributeViewFieldViews, or createAttributeViewItem* with a required,trim string field (e.g. avID, srcIDs values) set to \"\", \"   \", or missing while required.","commonSituations":"Row/column IDs extracted from UI state that came back empty, copy/paste flows where the source selection was empty, API scripts hardcoding blank strings during testing.","solutions":["Provide a non-empty, trimmed value for the flagged field","Validate inputs client-side (trim + length check) before invoking the endpoint","If the field should be optional, verify you are calling the right endpoint for your use case"],"exampleFix":"// before\nfetchPost(\"/api/av/getAttributeViewPasteRows\", {avID: \"  \", srcIDs});\n// after\nconst id = avID.trim();\nif (!id) throw new Error(\"avID is required\");\nfetchPost(\"/api/av/getAttributeViewPasteRows\", {avID: id, srcIDs});","handlingStrategy":"validation","validationCode":"function assertTrimmed(payload, names) { for (const n of names) { const v = payload[n]; if (typeof v !== \"string\" || !v.trim()) throw new Error(`Field [${n}] must not be empty`); } }","typeGuard":"const isTrimmedNonEmpty = (v) => typeof v === \"string\" && v.trim() !== \"\";","tryCatchPattern":"try { await post(avEndpoint, payload); } catch (e) { if (/must not be empty/.test(e.message)) { /* surface which field: e.message */ } else throw e; }","preventionTips":["Trim ID strings at the source (UI selection, clipboard) before storing them","Guard against empty selections before issuing paste/field-view calls","Keep a helper that validates av endpoints' required trimmed fields"],"tags":["validation","api","empty-input"],"backgroundTag":"empty-required-field","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"}