siyuan-note/siyuan · error

attribute view instance is not set

Error message

attribute view instance is not set

What it means

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.

Solutions

  1. Construct the value with NewAVTableInstance/NewAVGalleryInstance/NewAVKanbanInstance instead of a zero-value literal
  2. Check the source of the layout object before constructing the instance; return AVViewNotFound instead of an empty union when the view cannot be loaded
  3. In tests, assert that response marshaling succeeds so zero-value unions fail fast
  4. Add a constructor for any new layout type and never assign nil pointers into AVViewInstance

Example fix

// before
inst := apicontract.AVViewInstance{}
inst.gallery = gallery
// after
inst := apicontract.NewAVGalleryInstance(gallery)
Defensive patterns

Strategy: validation

Validate before calling

func validAVViewInstance(v apicontract.AVViewInstance) bool {
    return v.String() != "" || marshalsOK(v) // or check via constructor-only usage
}
// simplest guard: always build via constructors
func asInstance(t *apicontract.AVTable) (apicontract.AVViewInstance, error) {
    if t == nil {
        return apicontract.AVViewInstance{}, errors.New("table is nil")
    }
    return apicontract.NewAVTableInstance(t), nil
}

Type guard

func isSetAVViewInstance(v apicontract.AVViewInstance) bool {
    return v.Table() != nil || v.Gallery() != nil || v.Kanban() != nil
}

Try / catch

data, err := json.Marshal(inst)
if err != nil {
    return fmt.Errorf("render av view: %w", err)
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/604d57ac103856ac. Report an issue: GitHub.

Appendix: source

Thrown at kernel/apicontract/av_union.go:30

	gallery *AVGallery
	kanban  *AVKanban
}

func NewAVTableInstance(value *AVTable) AVViewInstance     { return AVViewInstance{table: value} }
func NewAVGalleryInstance(value *AVGallery) AVViewInstance { return AVViewInstance{gallery: value} }
func NewAVKanbanInstance(value *AVKanban) AVViewInstance   { return AVViewInstance{kanban: value} }

func (value AVViewInstance) MarshalJSON() ([]byte, error) {
	if value.table != nil {
		return json.Marshal(value.table)
	}
	if value.gallery != nil {
		return json.Marshal(value.gallery)
	}
	if value.kanban != nil {
		return json.Marshal(value.kanban)
	}
	return nil, errors.New("attribute view instance is not set")
}

func avPayloadSchema(b *schemaBuilder, t reflect.Type, input bool) (*Schema, error) {
	if t == reflect.TypeFor[*AVValuePatch]() {
		schema, err := b.schema(reflect.TypeFor[AVValue](), input)
		return nullable(schema), err
	}
	if t == reflect.TypeFor[AVValuePatch]() {
		return b.schema(reflect.TypeFor[AVValue](), input)
	}
	switch t {
	case reflect.TypeFor[AVTable](), reflect.TypeFor[AVTableColumn](), reflect.TypeFor[AVTableCell](),
		reflect.TypeFor[AVGallery](), reflect.TypeFor[AVGalleryField](), reflect.TypeFor[AVGalleryFieldValue](),
		reflect.TypeFor[AVKanban](), reflect.TypeFor[AVKanbanField](), reflect.TypeFor[AVKanbanFieldValue](),
		reflect.TypeFor[AVLayoutTable](), reflect.TypeFor[AVViewTableColumn](), reflect.TypeFor[AVLayoutGallery](),
		reflect.TypeFor[AVViewGalleryCardField](), reflect.TypeFor[AVLayoutKanban](), reflect.TypeFor[AVViewKanbanField]():
		return avEmbeddedPayloadSchema(b, t, input)
	}

View on GitHub (pinned to 9f775e8a12)