{"record":{"id":"a56620899ca5330d","repo":"siyuan-note/siyuan","slug":"field-id-should-be-of-type-string","errorCode":null,"errorMessage":"Field [id] should be of type [String]","messagePattern":"Field \\[id\\] should be of type \\[String\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/apicontract/block_info_decode.go","lineNumber":17,"sourceCode":"package apicontract\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"io\"\n\t\"reflect\"\n)\n\nfunc init() {\n\tendpoint := GetBlockInfo\n\tGetBlockInfo.decodeRequest = func(reader io.Reader) (BlockInfoRequest, error) {\n\t\trequest, err := endpoint.Decode(reader)\n\t\tvar typeError *json.UnmarshalTypeError\n\t\t// 块信息入口保留 ID 类型错误的既有消息。\n\t\tif errors.As(err, &typeError) && typeError.Type.Kind() == reflect.String {\n\t\t\treturn request, errors.New(\"Field [id] should be of type [String]\")\n\t\t}\n\t\treturn request, err\n\t}\n}\n","sourceCodeStart":1,"sourceCodeEnd":22,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/apicontract/block_info_decode.go#L1-L22","documentation":"The block-info endpoint requires the id field to be a JSON string. The generic decoder would return a raw Go UnmarshalTypeError; this endpoint installs a custom decodeRequest that detects that case for string-typed fields and replaces it with the stable, human-readable message 'Field [id] should be of type [String]' for backward compatibility.","triggerScenarios":"POSTing to /api/block/getBlockInfo with {\"id\":12345} (numeric ID), {\"id\":true}, or an object/array instead of a quoted block ID string.","commonSituations":"Numeric IDs coming from databases or spreadsheet data, JS clients that strip quotes via template/eval mistakes, or copy-pasting a block ID that was accidentally coerced to a number (e.g. an all-digit ID in a weakly typed script).","solutions":["Send id as a quoted JSON string: {\"id\":\"20240101120000-abcdefg\"}.","Coerce numeric-looking IDs to strings on the client before sending (String(id)).","Check where the ID originates (DB row, CSV) and ensure it is kept as text end-to-end.","If the error persists, print the raw request body to confirm the JSON type of id."],"exampleFix":"// before\n{\"id\": 20240101120000}\n// after\n{\"id\": \"20240101120000-abcdefg\"}","handlingStrategy":"type-guard","validationCode":"if (typeof payload.id !== \"string\") { payload.id = String(payload.id); }","typeGuard":"const isBlockId = (v) => typeof v === \"string\" && v.length > 0;","tryCatchPattern":"try {\n  await post(\"/api/block/getBlockInfo\", {id});\n} catch (e) {\n  if (String(e.message).includes(\"Field [id] should be of type [String]\")) {\n    await post(\"/api/block/getBlockInfo\", {id: String(id)});\n  } else { throw e; }\n}","preventionTips":["Keep block IDs as strings from source (DB, CSV) to send","Never let CSV/spreadsheet importers coerce all-digit IDs to numbers","Add a runtime typeof check at the API client boundary","Log the payload when this error occurs to spot coercion sources"],"tags":["json","type-mismatch","block-id","api"],"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"}