{"record":{"id":"c105267d4f2224bb","repo":"siyuan-note/siyuan","slug":"element-d-w","errorCode":null,"errorMessage":"element [%d]: %w","messagePattern":"element \\[(.+?)\\]: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/apicontract/decode.go","lineNumber":192,"sourceCode":"\tswitch value.Kind() {\n\tcase reflect.Pointer:\n\t\tvalue.Set(reflect.New(value.Type().Elem()))\n\t\treturn decodeRequestValue(raw, value.Elem())\n\tcase reflect.Struct:\n\t\tvar fields map[string]json.RawMessage\n\t\tif err := json.Unmarshal(raw, &fields); err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn decodeRequestFields(value, fields)\n\tcase reflect.Slice:\n\t\tvar entries []json.RawMessage\n\t\tif err := json.Unmarshal(raw, &entries); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tvalue.Set(reflect.MakeSlice(value.Type(), len(entries), len(entries)))\n\t\tfor i, entry := range entries {\n\t\t\tif err := decodeRequestValue(entry, value.Index(i)); err != nil {\n\t\t\t\treturn fmt.Errorf(\"element [%d]: %w\", i, err)\n\t\t\t}\n\t\t}\n\t\treturn nil\n\tcase reflect.Map:\n\t\tvar entries map[string]json.RawMessage\n\t\tif err := json.Unmarshal(raw, &entries); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tvalue.Set(reflect.MakeMapWithSize(value.Type(), len(entries)))\n\t\tfor key, entry := range entries {\n\t\t\tchild := reflect.New(value.Type().Elem()).Elem()\n\t\t\tif err := decodeRequestValue(entry, child); err != nil {\n\t\t\t\treturn fmt.Errorf(\"entry [%s]: %w\", key, err)\n\t\t\t}\n\t\t\tvalue.SetMapIndex(reflect.ValueOf(key).Convert(value.Type().Key()), child)\n\t\t}\n\t\treturn nil\n\tdefault:","sourceCodeStart":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/apicontract/decode.go#L174-L210","documentation":"When decoding a JSON array into a slice-typed contract field, decodeRequestValue decodes each element recursively and wraps any per-element failure as \"element [%d]: %w\" with the failing index. The error indicates which element of the array failed to decode, with the underlying cause appended via %w. It is positional diagnostics over the apicontract strict decoder.","triggerScenarios":"Calling any kernel API with an array field (e.g. srcs, ids, av column lists) where at least one element does not match the slice's element type — e.g. [\"a\", null, 3] for a []string field, or an object inside a string array.","commonSituations":"Bulk operations over lists of block/notebook IDs where one entry is null or a number; JavaScript arrays with mixed types; payloads serialized from Set/Map objects producing unexpected element shapes.","solutions":["Inspect the reported index and fix that element's type to match the declared element type","Validate every array element is a string/valid JSON of the right type before sending","Filter out null/undefined entries from the array client-side","Check the endpoint contract in kernel/apicontract/ for the exact element type"],"exampleFix":"// before\nsrcs: [\"a.sy\", null, \"c.sy\"]\n// after\nsrcs: [\"a.sy\", \"c.sy\"].filter(Boolean)","handlingStrategy":"validation","validationCode":"function validateArray(arr, check) {\n  if (!Array.isArray(arr)) return;\n  arr.forEach((el, i) => { if (!check(el)) throw new Error(`element [${i}] invalid`); });\n}\nvalidateArray(payload.srcs, (s) => typeof s === \"string\");","typeGuard":"const allOfType = (arr, t) => Array.isArray(arr) && arr.every((x) => typeof x === t);","tryCatchPattern":"try { await fetchPost(url, payload); } catch (e) { const m = String(e).match(/element \\[(\\d+)]/); if (m) console.error(\"Bad array element at\", m[1], payload.ids[m[1]]); }","preventionTips":["Validate element types before sending arrays","Filter null/undefined from arrays built from mixed sources","Avoid mixed-type JS arrays in payloads","Derive ID lists from APIs that guarantee strings"],"tags":["api","json","array","validation"],"backgroundTag":"type-mismatch","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"}