{"record":{"id":"471697f5c67b06ba","repo":"siyuan-note/siyuan","slug":"field-s-must-not-be-empty-export","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/export.go","lineNumber":258,"sourceCode":"\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}\n\t\t\tdest.SetString(text)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc bindExportDecoder[Request, Data any](endpoint *Endpoint[Request, Data]) {\n\tendpoint.decodeRequest = func(reader io.Reader) (request Request, err error) {\n\t\tfields, err := blockRequestFields(reader, endpoint.Definition().Path)\n\t\tif err != nil {\n\t\t\treturn request, err\n\t\t}\n\t\terr = decodeExportFields(reflect.ValueOf(&request).Elem(), fields)\n\t\treturn request, err\n\t}\n}\n","sourceCodeStart":240,"sourceCodeEnd":276,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/apicontract/export.go#L240-L276","documentation":"Fields marked with the trim constraint in export contracts are whitespace-trimmed, and if the trimmed string is empty, decodeExportFields returns \"Field [%s] must not be empty\". It catches values that are present but effectively blank — spaces, tabs, newlines — for fields the endpoint cannot operate on without content.","triggerScenarios":"Calling an export API with a required trim field set to \"\" or \"   \" (whitespace only), e.g. an empty id, path, or title after trimming.","commonSituations":"Form inputs from the UI submitted without validation; string interpolation producing \"  \" (e.g. `  ${undefined}` edge cases avoided but `${x}` empty); template defaults of empty string left unconfigured.","solutions":["Supply a non-empty value for the field named in the error","Trim/validate the value client-side before the request and reject empty input in your UI","Fall back to a valid default when the primary value is blank","Confirm with the API docs which fields are required and non-blank"],"exampleFix":"// before\nconst id = input.value.trim(); fetchPost(\"/api/export/exportMd\", { id });\n// after\nconst id = input.value.trim(); if (!id) return alert(\"id required\"); fetchPost(\"/api/export/exportMd\", { id });","handlingStrategy":"validation","validationCode":"function requireNonBlank(payload, names) {\n  for (const n of names) {\n    if (typeof payload[n] === \"string\" && payload[n].trim() === \"\") throw new Error(`Field [${n}] must not be empty`);\n  }\n}\nrequireNonBlank(payload, [\"id\"]);","typeGuard":"const isNonBlankString = (v) => typeof v === \"string\" && v.trim().length > 0;","tryCatchPattern":"try { await exportApi(payload); } catch (e) { if (String(e).includes(\"must not be empty\")) return alert(\"Please fill in all required inputs\"); throw e; }","preventionTips":["Trim and check inputs in your UI before submitting","Treat whitespace-only input as empty everywhere","Require explicit user input for blank-prone fields","Add client-side form validation mirroring trim constraints"],"tags":["api","validation","empty-value","export"],"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"}