{"record":{"id":"3c80f0d77a6e3f3c","repo":"siyuan-note/siyuan","slug":"attribute-view-is-required","errorCode":null,"errorMessage":"attribute view is required","messagePattern":"attribute view is required","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/attribute_view_create.go","lineNumber":126,"sourceCode":"\tview, viewErr := attrView.GetFirstView()\n\tif nil != viewErr {\n\t\treturn nil, databaseCreationError(viewErr, cleanupCreatedAttributeView(blockID, avID))\n\t}\n\tif err = SetDatabaseBlockView(blockID, avID, view.ID); nil != err {\n\t\treturn nil, databaseCreationError(err, cleanupCreatedAttributeView(blockID, avID))\n\t}\n\n\tif bt := treenode.GetBlockTree(blockID); nil != bt {\n\t\tutil.PushReloadProtyle(bt.RootID)\n\t}\n\tReloadAttrView(avID)\n\tret = &AttributeViewCreateResult{BlockID: blockID, AvID: avID, ViewID: view.ID, AttributeView: attrView}\n\treturn\n}\n\nfunc configureCreatedAttributeView(attrView *av.AttributeView, name, primaryKeyName string, preparedKeys []*av.Key) (err error) {\n\tif nil == attrView {\n\t\treturn errors.New(\"attribute view is required\")\n\t}\n\tcurrentView, err := attrView.GetFirstView()\n\tif nil != err {\n\t\treturn\n\t}\n\tblockKeyValues := attrView.GetBlockKeyValues()\n\tif nil == blockKeyValues || nil == blockKeyValues.Key {\n\t\treturn errors.New(\"attribute view has no primary key field\")\n\t}\n\n\tif name = strings.TrimSpace(name); \"\" != name {\n\t\tname = strings.ReplaceAll(name, \"\\n\", \" \")\n\t\tif 512 < utf8.RuneCountInString(name) {\n\t\t\tname = string([]rune(name)[:512])\n\t\t}\n\t\tattrView.Name = name\n\t}\n\tif primaryKeyName = strings.TrimSpace(primaryKeyName); \"\" != primaryKeyName {","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/attribute_view_create.go#L108-L144","documentation":"configureCreatedAttributeView is an internal step that wires the view name, primary key, and initial view configuration into a freshly created av.AttributeView. It refuses a nil attribute view because there is nothing to configure and proceeding would panic later.","triggerScenarios":"Calling configureCreatedAttributeView directly (tests do this) with a nil *av.AttributeView; in production this indicates a bug where CreateAttributeViewDatabase produced a nil attrView without returning an error.","commonSituations":"Unit tests exercising the configure step against a hand-built or nil view; a refactoring that changed the construction order so attrView is nil when configuration runs.","solutions":["Construct or load a valid *av.AttributeView (e.g. via av.NewAttributeView) before calling configureCreatedAttributeView","In tests, build a fixture attribute view with at least a block key before invoking the helper","If hit in production paths, check that the earlier creation steps returned non-nil attrView and an error was not swallowed"],"exampleFix":"// before\nerr := configureCreatedAttributeView(nil, \"My DB\", \"Name\", keys)\n// after\nattrView := av.NewAttributeView(ast.NewNodeID())\nerr := configureCreatedAttributeView(attrView, \"My DB\", \"Name\", keys)","handlingStrategy":"validation","validationCode":"if attrView == nil {\n    return errors.New(\"attrView must be constructed before configuration\")\n}","typeGuard":"func isNilAttrView(v *av.AttributeView) bool { return v == nil }","tryCatchPattern":"if err := configureCreatedAttributeView(attrView, name, pk, keys); err != nil {\n    return fmt.Errorf(\"configure created attribute view: %w\", err)\n}","preventionTips":["In tests, construct fixtures via the same factory functions production code uses","Never pass a nil attribute view; build one with av.NewAttributeView first","Ensure creation and configuration happen in one guarded sequence"],"tags":["internal","null-check","attribute-view","go"],"backgroundTag":"null-argument","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}