{"record":{"id":"828274f0fbfbb7e1","repo":"siyuan-note/siyuan","slug":"list-notebook-attribute-views-s-failed-w","errorCode":null,"errorMessage":"list notebook attribute views [%s] failed: %w","messagePattern":"list notebook attribute views \\[(.+?)\\] failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/inline_style.go","lineNumber":426,"sourceCode":"\t\tif strict {\n\t\t\treturn nil, fmt.Errorf(\"list attribute views failed: %w\", err)\n\t\t}\n\t\tlogging.LogWarnf(\"list attribute views for custom color refresh failed: %s\", err)\n\t}\n\tentries, readErr := os.ReadDir(util.DataDir)\n\tif readErr != nil && !os.IsNotExist(readErr) {\n\t\tif strict {\n\t\t\treturn nil, fmt.Errorf(\"list workspace data directory failed: %w\", readErr)\n\t\t}\n\t\tlogging.LogWarnf(\"list workspace data directory for custom color refresh failed: %s\", readErr)\n\t}\n\tfor _, entry := range entries {\n\t\tif !entry.IsDir() || !ast.IsNodeIDPattern(entry.Name()) {\n\t\t\tcontinue\n\t\t}\n\t\tif err = appendPaths(filepath.Join(util.DataDir, entry.Name(), \"storage\", \"av\")); err != nil {\n\t\t\tif strict {\n\t\t\t\treturn nil, fmt.Errorf(\"list notebook attribute views [%s] failed: %w\", entry.Name(), err)\n\t\t\t}\n\t\t\tlogging.LogWarnf(\"list notebook attribute views [%s] for custom color refresh failed: %s\",\n\t\t\t\tentry.Name(), err)\n\t\t}\n\t}\n\tsort.Strings(paths)\n\tfor _, path := range paths {\n\t\tavID, indexes, readErr := av.ReadAttributeViewCustomColorUsageByPath(path)\n\t\tif readErr != nil {\n\t\t\tif strict {\n\t\t\t\treturn nil, fmt.Errorf(\"read attribute view custom color usage [%s] failed: %w\", avID, readErr)\n\t\t\t}\n\t\t\tlogging.LogWarnf(\"read attribute view custom color usage [%s] for refresh failed: %s\", avID, readErr)\n\t\t\tcontinue\n\t\t}\n\t\tused := ret[avID]\n\t\tif used == nil {\n\t\t\tused = map[int]struct{}{}","sourceCodeStart":408,"sourceCodeEnd":444,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/inline_style.go#L408-L444","documentation":"workspaceAttributeViewCustomColorUsage walks every notebook under DataDir and lists the storage/av directory of each to find attribute-view files whose custom color usage must be refreshed. When listing a notebook's av directory fails and strict mode is on, the whole operation is aborted and this wrapped error is returned to setInlineStylesData. In non-strict mode the failure is only logged as a warning and the remaining notebooks are still processed.","triggerScenarios":"Calling the inline-styles update path (setInlineStylesData) that triggers workspaceAttributeViewCustomColorUsage with strict=true, while os.ReadDir on <data>/<notebookID>/storage/av fails: the notebook directory exists but storage/av is missing or unreadable, or an OS-level permission/I/O error occurs on that directory.","commonSituations":"A notebook folder left half-deleted (storage/av removed manually or by a partial sync), restrictive file permissions after copying the workspace between users/machines, cloud-sync clients placing the directory in a broken state, or a directory named like a notebook ID that is not a real notebook.","solutions":["Check that <workspace>/data/<notebookID>/storage/av exists and is readable; recreate the directory or fix its permissions","If the folder is a stale orphan (ID-shaped directory that is not a notebook), remove it or move it out of data/","Retry the operation after fixing the filesystem; the error wraps the underlying os error which names the exact cause","If non-critical, use the non-strict path where the failure is only logged and other notebooks continue processing"],"exampleFix":"// before: notebook dir exists but storage/av missing -> strict call aborts\nif err = appendPaths(filepath.Join(util.DataDir, entry.Name(), \"storage\", \"av\")); err != nil {\n    return nil, fmt.Errorf(\"list notebook attribute views [%s] failed: %w\", entry.Name(), err)\n}\n// after: ensure the directory exists (or skip gracefully) before the strict scan\nos.MkdirAll(filepath.Join(util.DataDir, entry.Name(), \"storage\", \"av\"), 0755)","handlingStrategy":"try-catch","validationCode":"const fs = require('fs');\nfunction avDirReadable(workspace, notebookID) {\n  try { fs.accessSync(`${workspace}/data/${notebookID}/storage/av`, fs.constants.R_OK); return true; }\n  catch { return false; }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await api.setInlineStylesData(payload);\n} catch (e) {\n  if (String(e).includes('list notebook attribute views')) {\n    // inspect wrapped OS error, repair or skip the notebook dir, then retry\n  } else throw e;\n}","preventionTips":["Never delete storage/av subdirectories manually while SiYuan is running","Keep uniform permissions across the workspace data directory","Exclude the workspace from aggressive cloud-sync clients that create half-synced directories"],"tags":["filesystem","attribute-view","notebook-scan","directory-listing"],"backgroundTag":"directory-not-found","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"}