{"record":{"id":"4f75edea58141268","repo":"siyuan-note/siyuan","slug":"database-field-name-and-type-are-required","errorCode":null,"errorMessage":"database field name and type are required","messagePattern":"database field name and type are required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/attribute_view_create.go","lineNumber":74,"sourceCode":"\t}\n\tif \"\" == previousID && \"\" == nextID {\n\t\tif err = treenode.CheckContainerParent(parentID); nil != err {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\tif \"\" == layout {\n\t\tlayout = av.LayoutTypeTable\n\t}\n\tswitch layout {\n\tcase av.LayoutTypeTable, av.LayoutTypeGallery, av.LayoutTypeKanban:\n\tdefault:\n\t\treturn nil, av.ErrWrongLayoutType\n\t}\n\n\tpreparedKeys := make([]*av.Key, 0, len(keySpecs))\n\tfor _, spec := range keySpecs {\n\t\tif nil == spec || \"\" == strings.TrimSpace(spec.Name) || \"\" == strings.TrimSpace(spec.Type) {\n\t\t\treturn nil, errors.New(\"database field name and type are required\")\n\t\t}\n\t\tkey, keyErr := newAttributeViewKey(ast.NewNodeID(), strings.TrimSpace(spec.Name), strings.TrimSpace(spec.Type), spec.Icon,\n\t\t\tav.DateDisplayFormatFull)\n\t\tif nil != keyErr {\n\t\t\treturn nil, keyErr\n\t\t}\n\t\tpreparedKeys = append(preparedKeys, key)\n\t}\n\n\tblockID, avID := ast.NewNodeID(), ast.NewNodeID()\n\tdata := fmt.Sprintf(`<div class=\"av\" data-node-id=\"%s\" data-av-id=\"%s\" data-type=\"NodeAttributeView\" data-av-type=\"%s\"></div>`,\n\t\tblockID, avID, layout)\n\toperation := &Operation{\n\t\tAction:     \"insert\",\n\t\tData:       data,\n\t\tParentID:   parentID,\n\t\tPreviousID: previousID,\n\t\tNextID:     nextID,","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/attribute_view_create.go#L56-L92","documentation":"Each field spec in keySpecs must carry a non-blank name and a non-blank type string, which newAttributeViewKey later maps to a concrete av.Key type. A nil spec, or a spec whose name/type is empty or whitespace-only, cannot produce a valid field, so the whole creation aborts.","triggerScenarios":"Passing a nil element in the keySpecs slice, or a spec with Name=\"\"/\"  \" or Type=\"\"/\"  \" to CreateAttributeViewDatabase.","commonSituations":"Building keySpecs programmatically from user input where an empty row slipped in; a mapping layer that emits specs for optional fields even when the user left them blank; typo where the type field was assigned to the wrong struct member.","solutions":["Ensure every spec has a trimmed, non-empty Name and a valid type string (e.g. \"text\", \"number\", \"select\", \"date\")","Filter out nil or blank specs before building the slice","Validate specs in the caller (or API handler) and return a clearer message about which field row is bad"],"exampleFix":"// before\nspecs := append(specs, &model.AttributeViewCreateKey{Name: userEnteredName, Type: userEnteredType}) // may be blank\n// after\nif strings.TrimSpace(userEnteredName) != \"\" && strings.TrimSpace(userEnteredType) != \"\" {\n    specs = append(specs, &model.AttributeViewCreateKey{Name: strings.TrimSpace(userEnteredName), Type: strings.TrimSpace(userEnteredType)})\n}","handlingStrategy":"validation","validationCode":"for i, spec := range keySpecs {\n    if spec == nil || strings.TrimSpace(spec.Name) == \"\" || strings.TrimSpace(spec.Type) == \"\" {\n        return fmt.Errorf(\"keySpecs[%d]: name and type are required\", i)\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Trim user-supplied field names and types before building specs","Skip empty UI rows instead of emitting blank specs","Validate types against the supported av key-type list before submission"],"tags":["api","validation","attribute-view","schema"],"backgroundTag":"missing-required-argument","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}