{"record":{"id":"06b7baa96c52ba65","repo":"siyuan-note/siyuan","slug":"field-sortmode-must-be-an-integer-or-null-s","errorCode":null,"errorMessage":"Field [sortMode] must be an integer or null: %s","messagePattern":"Field \\[sortMode\\] must be an integer or null: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/apicontract/filetree_input.go","lineNumber":130,"sourceCode":"\t\tdelete(fields, \"querySubTypes\")\n\t\tif value, ok := filtered[\"subTypes\"]; ok {\n\t\t\tfields[\"querySubTypes\"] = value\n\t\t}\n\t}\n\treturn fileTreeBind[FileTreeGetDocOptions](fields)\n}\n\nfunc (r FileTreeSortModeRequest) Mode() (*int, error) {\n\traw := r.sortModeFields[\"sortMode\"]\n\tif len(raw) == 0 {\n\t\treturn nil, fmt.Errorf(\"Field [sortMode] is required\")\n\t}\n\tif bytes.Equal(bytes.TrimSpace(raw), []byte(\"null\")) {\n\t\treturn nil, nil\n\t}\n\tvar value int\n\tif err := json.Unmarshal(raw, &value); err != nil {\n\t\treturn nil, fmt.Errorf(\"Field [sortMode] must be an integer or null: %s\", err)\n\t}\n\treturn &value, nil\n}\n\nfunc init() {\n\tfileTreeJSONDecoder(&MoveLocalShorthands)\n\tfileTreeJSONDecoder(&UpsertIndexes)\n\tfileTreeJSONDecoder(&RemoveIndexes)\n\tfileTreeJSONDecoder(&Doc2Heading)\n\tfileTreeJSONDecoder(&GetHPathByPath)\n\tfileTreeJSONDecoder(&GetHPathsByPaths)\n\tfileTreeJSONDecoder(&GetHPathByID)\n\tfileTreeJSONDecoder(&GetFullHPathByID)\n\tfileTreeJSONDecoder(&MoveDocs)\n\tfileTreeJSONDecoder(&MoveDocsByID)\n\tfileTreeJSONDecoder(&RemoveDoc)\n\tfileTreeJSONDecoder(&RemoveDocs)\n\tfileTreeJSONDecoder(&RenameDoc)","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/apicontract/filetree_input.go#L112-L148","documentation":"Once present, the raw 'sortMode' value must unmarshal into a Go int or be JSON null. Anything else (string \"7\", bool, object, float with fraction) fails json.Unmarshal into int and produces this message with the underlying decoder error appended. The library is strict because sortMode maps directly to an enum-like integer in the kernel config.","triggerScenarios":"POST /api/filetree/setDocSortMode with {\"id\":\"...\",\"sortMode\":\"7\"} or sortMode: 1.5 or sortMode: {\"mode\":7}.","commonSituations":"JavaScript clients that keep the mode as a numeric string from a select element; JSON produced by template interpolation without type conversion; API consumers guessing the field is a string code like \"name\".","solutions":["Convert the value to an integer before sending, e.g. parseInt(mode, 10)","Send null explicitly if clearing the mode is intended","Consult the API docs for the valid integer sort-mode codes"],"exampleFix":"// before\nfetchPost(\"/api/filetree/setDocSortMode\", { id, sortMode: String(mode) });\n// after\nfetchPost(\"/api/filetree/setDocSortMode\", { id, sortMode: Number.parseInt(mode, 10) });","handlingStrategy":"type-guard","validationCode":"if (!Number.isInteger(sortMode)) throw new TypeError(`sortMode must be an integer, got ${typeof sortMode}`);","typeGuard":"const isSortMode = (v) => v === null || Number.isInteger(v);","tryCatchPattern":"try {\n  await fetchPost(\"/api/filetree/setDocSortMode\", { id, sortMode });\n} catch (e) {\n  if (String(e.message).includes(\"must be an integer or null\")) {\n    await fetchPost(\"/api/filetree/setDocSortMode\", { id, sortMode: parseInt(sortMode, 10) });\n  }\n}","preventionTips":["Parse string modes with parseInt/Number before sending","Never send float or object values for enum-like integer fields","Type the payload in TypeScript to catch coercion at compile time"],"tags":["type-mismatch","api-request","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"}