{"record":{"id":"604d57ac103856ac","repo":"siyuan-note/siyuan","slug":"attribute-view-instance-is-not-set","errorCode":null,"errorMessage":"attribute view instance is not set","messagePattern":"attribute view instance is not set","errorType":"exception","errorClass":null,"httpStatus":500,"severity":"error","filePath":"kernel/apicontract/av_union.go","lineNumber":30,"sourceCode":"\tgallery *AVGallery\n\tkanban  *AVKanban\n}\n\nfunc NewAVTableInstance(value *AVTable) AVViewInstance     { return AVViewInstance{table: value} }\nfunc NewAVGalleryInstance(value *AVGallery) AVViewInstance { return AVViewInstance{gallery: value} }\nfunc NewAVKanbanInstance(value *AVKanban) AVViewInstance   { return AVViewInstance{kanban: value} }\n\nfunc (value AVViewInstance) MarshalJSON() ([]byte, error) {\n\tif value.table != nil {\n\t\treturn json.Marshal(value.table)\n\t}\n\tif value.gallery != nil {\n\t\treturn json.Marshal(value.gallery)\n\t}\n\tif value.kanban != nil {\n\t\treturn json.Marshal(value.kanban)\n\t}\n\treturn nil, errors.New(\"attribute view instance is not set\")\n}\n\nfunc avPayloadSchema(b *schemaBuilder, t reflect.Type, input bool) (*Schema, error) {\n\tif t == reflect.TypeFor[*AVValuePatch]() {\n\t\tschema, err := b.schema(reflect.TypeFor[AVValue](), input)\n\t\treturn nullable(schema), err\n\t}\n\tif t == reflect.TypeFor[AVValuePatch]() {\n\t\treturn b.schema(reflect.TypeFor[AVValue](), input)\n\t}\n\tswitch t {\n\tcase reflect.TypeFor[AVTable](), reflect.TypeFor[AVTableColumn](), reflect.TypeFor[AVTableCell](),\n\t\treflect.TypeFor[AVGallery](), reflect.TypeFor[AVGalleryField](), reflect.TypeFor[AVGalleryFieldValue](),\n\t\treflect.TypeFor[AVKanban](), reflect.TypeFor[AVKanbanField](), reflect.TypeFor[AVKanbanFieldValue](),\n\t\treflect.TypeFor[AVLayoutTable](), reflect.TypeFor[AVViewTableColumn](), reflect.TypeFor[AVLayoutGallery](),\n\t\treflect.TypeFor[AVViewGalleryCardField](), reflect.TypeFor[AVLayoutKanban](), reflect.TypeFor[AVViewKanbanField]():\n\t\treturn avEmbeddedPayloadSchema(b, t, input)\n\t}","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/apicontract/av_union.go#L12-L48","documentation":"AVViewInstance is a tagged union over table/gallery/kanban view instances; MarshalJSON serializes whichever variant pointer is non-nil. If the struct was created as a zero value (AVViewInstance{}) instead of via NewAVTableInstance/NewAVGalleryInstance/NewAVKanbanInstance, no variant is set and marshaling fails with this error, preventing an invalid empty union from ever reaching the API response.","triggerScenarios":"Marshaling an AVViewInstance value that was declared as a zero-value literal, copied from a zero struct, or built by code that forgot to call one of the three constructors; typically surfaces as a 500 during serialization of an attribute-view render response.","commonSituations":"A developer adds a new code path building AVViewInstance manually with AVViewInstance{...} but omits the layout field; refactoring renames a constructor call; a table variable is nil after a failed lookup and stored directly.","solutions":["Construct the value with NewAVTableInstance/NewAVGalleryInstance/NewAVKanbanInstance instead of a zero-value literal","Check the source of the layout object before constructing the instance; return AVViewNotFound instead of an empty union when the view cannot be loaded","In tests, assert that response marshaling succeeds so zero-value unions fail fast","Add a constructor for any new layout type and never assign nil pointers into AVViewInstance"],"exampleFix":"// before\ninst := apicontract.AVViewInstance{}\ninst.gallery = gallery\n// after\ninst := apicontract.NewAVGalleryInstance(gallery)","handlingStrategy":"validation","validationCode":"func validAVViewInstance(v apicontract.AVViewInstance) bool {\n    return v.String() != \"\" || marshalsOK(v) // or check via constructor-only usage\n}\n// simplest guard: always build via constructors\nfunc asInstance(t *apicontract.AVTable) (apicontract.AVViewInstance, error) {\n    if t == nil {\n        return apicontract.AVViewInstance{}, errors.New(\"table is nil\")\n    }\n    return apicontract.NewAVTableInstance(t), nil\n}","typeGuard":"func isSetAVViewInstance(v apicontract.AVViewInstance) bool {\n    return v.Table() != nil || v.Gallery() != nil || v.Kanban() != nil\n}","tryCatchPattern":"data, err := json.Marshal(inst)\nif err != nil {\n    return fmt.Errorf(\"render av view: %w\", err)\n}","preventionTips":["Only create AVViewInstance through the NewAV*Instance constructors","Never store a possibly-nil layout pointer into the union","Add CI tests that marshal every response variant","Return a not-found failure type instead of an empty union"],"tags":["go","json-marshal","union-type","attribute-view"],"backgroundTag":"internal-invariant-violation","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"}