siyuan-note/siyuan · error

ErrViewNotFound

ErrViewNotFound

Error message

view not found

What it means

ErrViewNotFound means the requested view (tab within an attribute view) could not be located. It is returned when the .av file does not exist on disk (parseAttributeViewByPathInBoxWithOptions), when the AV has no usable first view (GetFirstView), and when an operation references a view ID that isn't present (syncAttrViewTableColWidth, foldAttrViewGroups, getAttrViewOperationView). The API layer maps it to a 'viewNotFound' data payload for the frontend.

Source

Thrown at kernel/av/av.go:1342

	ret = filepath.Join(av, avID+".json")
	if !gulu.File.IsDir(av) {
		if err := os.MkdirAll(av, 0755); err != nil {
			logging.LogErrorf("create attribute view dir failed: %s", err)
			return
		}
	}
	return
}

func GetAttributeViewI18n(key string) string {
	return util.AttrViewLangs[util.Lang][key].(string)
}

var (
	ErrAttributeViewNotFound  = errors.New("attribute view not found")
	ErrInvalidAttributeViewID = errors.New("invalid attribute view id")
	ErrInvalidBoxID           = errors.New("invalid box id")
	ErrViewNotFound           = errors.New("view not found")
	ErrKeyNotFound            = errors.New("key not found")
	ErrItemNotFound           = errors.New("item not found")
	ErrWrongLayoutType        = errors.New("wrong layout type")
	ErrInvalidColumnAlign     = errors.New("invalid column align")
	ErrSpecTooNew             = errors.New("attribute view spec is too new")
	ErrRichTextSpecMismatch   = errors.New("attribute view rich text requires storage spec 9")
	ErrFilterTooDeep          = errors.New("filter nesting depth exceeds the maximum allowed")
)

const (
	NodeAttrNameAvs        = "custom-avs"                  // 用于标记块所属的属性视图,逗号分隔 av id
	NodeAttrView           = "custom-sy-av-view"           // 用于标记块所属的属性视图视图 view id Database block support specified view https://github.com/siyuan-note/siyuan/issues/10443
	NodeAttrVisibleViewIDs = "custom-sy-av-visible-views"  // 用于标记数据库块显示的视图 ID,逗号分隔
	NodeAttrContextFilter  = "custom-sy-av-context-filter" // 用于保存数据库块独有的上下文筛选配置
	NodeAttrViewStaticText = "custom-sy-av-s-text"         // 用于标记块所属的属性视图静态文本 Database-bound block primary key supports setting static anchor text https://github.com/siyuan-note/siyuan/issues/10049

	NodeAttrViewNames = "av-names" // 用于临时标记块所属的属性视图名称,空格分隔
)

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Re-fetch the AV's current view list (RenderAttributeView) and use the returned active view ID instead of a cached one
  2. Fall back to GetFirstView / the default view when the stored view ID is absent
  3. Verify the .av file exists in storage/av for the given notebook
  4. Handle the API payload {"error":"viewNotFound"} in frontend code by reloading the database view

Example fix

// before
err := setAttrViewSort(avID, staleViewID, sorts) // ErrViewNotFound
// after
attrView, _ := av.ParseAttributeView(avID)
viewID := staleViewID
if _, err := attrView.GetView(viewID); errors.Is(err, av.ErrViewNotFound) {
    view, _ := attrView.GetFirstView()
    viewID = view.ID
}
err := setAttrViewSort(avID, viewID, sorts)
Defensive patterns

Strategy: fallback

Validate before calling

attrView, err := av.ParseAttributeView(avID)
if err != nil { return err }
for _, v := range attrView.Views {
    if v.ID == viewID { return nil } // requested view exists, safe to proceed
}
return errors.New("view no longer exists; use GetFirstView fallback")

Type guard

func viewExists(attrView *av.AttributeView, viewID string) bool {
    _, err := attrView.GetView(viewID)
    return !errors.Is(err, av.ErrViewNotFound)
}

Try / catch

err := doViewOp(avID, viewID)
if errors.Is(err, av.ErrViewNotFound) {
    if first, ferr := attrView.GetFirstView(); ferr == nil {
        err = doViewOp(avID, first.ID) // fall back to the first view
    }
}

Prevention

When it happens

Trigger: Referencing a stale/deleted viewID in attribute-view operations (sort/filter/fold/column width) against an AV whose JSON no longer contains that view; the .av file missing on disk; operating on an AV with zero views.

Common situations: A plugin cached a view ID and the view was later deleted or replaced; sync merged AVs and dropped a view; the frontend sent operations for a view from before a database re-creation; a notebook moved without its storage/av directory.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/ba1cdf7531edd04c. Report an issue: GitHub.