{"record":{"id":"a29408281d908ebf","repo":"siyuan-note/siyuan","slug":"field-s-is-required-export","errorCode":null,"errorMessage":"Field [%s] is required","messagePattern":"Field \\[(.+?)\\] is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/apicontract/export.go","lineNumber":241,"sourceCode":"\t\t\tvar entries []json.RawMessage\n\t\t\tvar values []string\n\t\t\tif json.Unmarshal(fields[name], &entries) == nil {\n\t\t\t\tfor _, entry := range entries {\n\t\t\t\t\tvar text string\n\t\t\t\t\tif json.Unmarshal(entry, &text) == nil && text != \"\" {\n\t\t\t\t\t\tvalues = append(values, text)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tdest.Set(reflect.ValueOf(values))\n\t\t\tcontinue\n\t\t}\n\t\traw := fields[name]\n\t\tif len(raw) == 0 || bytes.Equal(bytes.TrimSpace(raw), []byte(\"null\")) {\n\t\t\tif has(\"optional\") {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn fmt.Errorf(\"Field [%s] is required\", name)\n\t\t}\n\t\tif err := decodeRequestValue(raw, dest); err != nil {\n\t\t\tif has(\"ignoretype\") || value.Type() == reflect.TypeFor[ExportTitleOptions]() && name == \"addTitle\" {\n\t\t\t\tdest.SetZero()\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tkind := dest.Kind()\n\t\t\tif kind == reflect.Pointer {\n\t\t\t\tkind = dest.Type().Elem().Kind()\n\t\t\t}\n\t\t\tkindName := map[reflect.Kind]string{reflect.String: \"String\", reflect.Bool: \"Boolean\", reflect.Float64: \"Number\", reflect.Slice: \"Array\"}[kind]\n\t\t\treturn fmt.Errorf(\"Field [%s] should be of type [%s]\", name, kindName)\n\t\t}\n\t\tif has(\"trim\") {\n\t\t\ttext := strings.TrimSpace(dest.String())\n\t\t\tif text == \"\" {\n\t\t\t\treturn fmt.Errorf(\"Field [%s] must not be empty\", name)\n\t\t\t}","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/apicontract/export.go#L223-L259","documentation":"decodeExportFields in kernel/apicontract/export.go enforces required fields on export-style endpoints: when a field's value is missing or the JSON literal null and it is not marked optional, the decoder returns \"Field [%s] is required\". Export request contracts (e.g. export endpoints decoded via Decode/decodeExportFields) require certain inputs to function.","triggerScenarios":"Calling an export API (e.g. /api/export/*) without a required field such as id/pth, or sending it as null; multipart or form bodies missing the field; clients dropping empty-string fields from the payload entirely when the field is required.","commonSituations":"Export-to-PDF/Word/image integrations that build payloads conditionally and skip empty values; plugin upgrades where a field was added as required after the plugin was written; template code with commented-out fields.","solutions":["Provide the required field named in the error with a valid value","Ensure the field is included even when empty if empty is meaningful for the endpoint","Update your client to the current API docs for the export endpoint","If the field genuinely is optional for your use, check whether the contract marks it optional and upgrade SiYuan or adjust the call"],"exampleFix":"// before\nconst payload = {}; // id omitted\n// after\nconst payload = { id: blockId };","handlingStrategy":"validation","validationCode":"function requireFields(payload, names) {\n  for (const n of names) {\n    if (payload[n] === undefined || payload[n] === null) throw new Error(`Field [${n}] is required`);\n  }\n}\nrequireFields(payload, [\"id\"]);","typeGuard":"const hasRequired = (o, n) => o[n] !== undefined && o[n] !== null;","tryCatchPattern":"try { await exportApi(payload); } catch (e) { const m = String(e).match(/Field \\[(\\w+)\\] is required/); if (m) return alert(`Missing field: ${m[1]}`); throw e; }","preventionTips":["Keep a checklist of required fields per export endpoint","Never drop empty-string fields conditionally without checking the contract","Validate payloads against the endpoint contract before sending","Update clients when SiYuan adds required export fields"],"tags":["api","validation","required-field","export"],"backgroundTag":"missing-required-argument","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"}