{"record":{"id":"bba0caa3915f9daf","repo":"siyuan-note/siyuan","slug":"attribute-view-snapshot-context-is-ambiguous-s","errorCode":null,"errorMessage":"attribute view snapshot context is ambiguous [%s]","messagePattern":"attribute view snapshot context is ambiguous \\[(.+?)\\]","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/attribute_view_render.go","lineNumber":1215,"sourceCode":"\tindex, err := repo.GetIndex(indexID)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tfiles, err := repo.GetFiles(index)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tvar matches []*entity.File\n\tfor _, file := range files {\n\t\tif strings.HasSuffix(file.Path, \"/storage/av/\"+avID+\".json\") {\n\t\t\tmatches = append(matches, file)\n\t\t}\n\t}\n\tif len(matches) == 0 {\n\t\treturn \"\", av.ErrAttributeViewNotFound\n\t}\n\tif len(matches) != 1 {\n\t\treturn \"\", fmt.Errorf(\"attribute view snapshot context is ambiguous [%s]\", avID)\n\t}\n\tboxID := avBoxIDFromRepoPath(matches[0].Path)\n\tif IsEncryptedBox(boxID) {\n\t\treturn boxID, nil\n\t}\n\treturn \"\", nil\n}\n\n// ResolveHistoryAttributeViewBoxID 返回历史属性视图的唯一加密笔记本上下文。\nfunc ResolveHistoryAttributeViewBoxID(avID, created string) (string, error) {\n\tif !ast.IsNodeIDPattern(avID) {\n\t\treturn \"\", ErrInvalidID\n\t}\n\tcreatedUnix, err := strconv.ParseInt(created, 10, 64)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"parse created [%s] failed: %w\", created, err)\n\t}\n\tdirPrefix := time.Unix(createdUnix, 0).Format(\"2006-01-02-150405\")","sourceCodeStart":1197,"sourceCodeEnd":1233,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/attribute_view_render.go#L1197-L1233","documentation":"ResolveRepoSnapshotAttributeViewBoxID searches repo snapshots for the attribute view file matching avID. Exactly one match is required to unambiguously determine the owning notebook (box) ID; when multiple snapshot paths contain the same avID, the context is ambiguous and this error is returned instead of guessing.","triggerScenarios":"The same attribute view file (same avID) exists in more than one notebook's snapshot path in the repository — e.g. the .av file was duplicated or copied between notebooks before snapshotting.","commonSituations":"Manually copying documents between notebooks causing duplicate av files; sync conflicts leaving the same attribute view in multiple boxes; restoring snapshots creating duplicates.","solutions":["Locate and remove/rename the duplicate attribute view file so only one snapshot path contains avID","Search the repo index for the avID across notebooks to identify which duplicate is stale","If duplicates are intentional, resolve at a higher level by passing explicit notebook context instead of relying on auto-resolution"],"exampleFix":"// before\nboxID, err := model.ResolveRepoSnapshotAttributeViewBoxID(avID) // ambiguous\n// after\n// deduplicate first, or pass explicit boxID:\nboxID, err := explicitBoxID, nil","handlingStrategy":"try-catch","validationCode":"matches := globRepoPaths(avID)\nif len(matches) == 0 { return ErrNotFound }\nif len(matches) > 1 { return ErrAmbiguous }","typeGuard":"func hasUniqueSnapshotMatch(matches []match) bool { return len(matches) == 1 }","tryCatchPattern":"boxID, err := model.ResolveRepoSnapshotAttributeViewBoxID(avID)\nif err != nil && strings.Contains(err.Error(), \"snapshot context is ambiguous\") {\n    return promptUserToPickNotebook(avID)\n}","preventionTips":["Avoid copying documents/databases between notebooks without regenerating IDs","Resolve sync conflicts promptly so av files are not duplicated","Audit the repo for duplicate av IDs after manual data manipulation"],"tags":["snapshot","ambiguity","repo"],"backgroundTag":"unexpected-response-shape","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"}