{"record":{"id":"c94468be887db6e3","repo":"siyuan-note/siyuan","slug":"field-s-must-not-be-empty-repo","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/repo.go","lineNumber":207,"sourceCode":"\tChunks  []string `json:\"chunks\"`  // 文件分块列表\n}\n\nfunc repoRequestFields(reader io.Reader, path string) (map[string]json.RawMessage, error) {\n\tfields, err := blockRequestFields(reader, path)\n\tif err != nil {\n\t\treturn nil, errors.New(strings.ReplaceAll(err.Error(), \"map[string]json.RawMessage\", \"map[string]interface {}\"))\n\t}\n\treturn fields, nil\n}\nfunc repoRequestString(fields map[string]json.RawMessage, key string, required, trim bool) (string, error) {\n\tvalue, err := legacyField[string](fields, key, \"String\", required)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tif trim && len(fields[key]) > 0 && string(fields[key]) != \"null\" {\n\t\tvalue = strings.TrimSpace(value)\n\t\tif value == \"\" {\n\t\t\treturn \"\", fmt.Errorf(\"Field [%s] must not be empty\", key)\n\t\t}\n\t}\n\treturn value, nil\n}\nfunc init() {\n\tSetRepoIndexRetentionDays.decodeRequest = func(reader io.Reader) (request SetRepoIndexRetentionDaysRequest, err error) {\n\t\tfields, err := repoRequestFields(reader, \"/api/repo/setRepoIndexRetentionDays\")\n\t\tif err != nil {\n\t\t\treturn request, err\n\t\t}\n\t\tif request.Days, err = legacyField[float64](fields, \"days\", \"Number\", true); err != nil {\n\t\t\treturn request, err\n\t\t}\n\t\treturn request, nil\n\t}\n\tSetRetentionIndexesDaily.decodeRequest = func(reader io.Reader) (request SetRetentionIndexesDailyRequest, err error) {\n\t\tfields, err := repoRequestFields(reader, \"/api/repo/setRetentionIndexesDaily\")\n\t\tif err != nil {","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/apicontract/repo.go#L189-L225","documentation":"repoRequestString extracts a string field from the decoded request fields. When trim is enabled and the field value trims down to an empty string, it rejects the request with 'Field [key] must not be empty'. It exists to enforce that required string parameters carry non-whitespace content.","triggerScenarios":"Calling a repo API endpoint whose decodeRequest uses repoRequestString with required=true (or with trim=true) and passing a value that is \"\", whitespace-only, or JSON null for the key.","commonSituations":"Frontend forms submitting empty inputs, copy-paste introducing trailing whitespace that is then trimmed away, or scripts sending placeholder empty strings for keys/passwords in repo operations.","solutions":["Provide a non-empty value for the named field in the request JSON","Trim-intent: check value.trim() !== '' before sending","Review which key is named in the error and map it to the client form field","If the field is truly optional, send it as JSON null or omit it rather than an empty string"],"exampleFix":"// before\nbody = JSON.stringify({ passphrase: '' })\n// after\nbody = JSON.stringify({ passphrase: 'my-passphrase' })","handlingStrategy":"validation","validationCode":"function requireNonEmpty(value: unknown, key: string): string {\n  const s = typeof value === 'string' ? value.trim() : '';\n  if (!s) throw new Error(`Field [${key}] must not be empty`);\n  return s;\n}","typeGuard":"function isNonEmptyString(v: unknown): v is string { return typeof v === 'string' && v.trim().length > 0; }","tryCatchPattern":"try { await post(url, body); } catch (e) { if (String(e).includes('must not be empty')) { highlightEmptyField(extractKey(e)); } }","preventionTips":["Check input.trim() !== '' before submitting forms","Disable submit until required fields are non-empty","Never send empty strings for optional fields — omit or send null","Map error keys back to form fields for user feedback"],"tags":["validation","http","empty-field"],"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"}