{"record":{"id":"57b598814c8b698c","repo":"siyuan-note/siyuan","slug":"invalid-attribute-view-json-s","errorCode":null,"errorMessage":"invalid attribute view JSON: %s","messagePattern":"invalid attribute view JSON: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/asset_relink.go","lineNumber":315,"sourceCode":"\t\tif err = p.observe(abs); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tp.reportProgress(abs)\n\t\tif entry.Type()&os.ModeSymlink != 0 {\n\t\t\treturn fmt.Errorf(\"symbolic attribute view is not supported: %s\", id)\n\t\t}\n\t\tif err = validateRelinkStoragePath(abs); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdata, err := filelock.ReadFile(abs)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif util.IsCiphertext(data) {\n\t\t\treturn fmt.Errorf(\"encrypted attribute view in global storage: %s\", id)\n\t\t}\n\t\tif !json.Valid(data) {\n\t\t\treturn fmt.Errorf(\"invalid attribute view JSON: %s\", id)\n\t\t}\n\t\tif !p.mayContainReferences(data) {\n\t\t\tcontinue\n\t\t}\n\t\tp.parsedViews++\n\t\tcache.RemoveAVData(id)\n\t\tview, err := av.ParseAttributeViewByPath(abs)\n\t\tif err != nil || view == nil || view.ID != id {\n\t\t\treturn fmt.Errorf(\"cannot parse attribute view %s: %v\", id, err)\n\t\t}\n\t\tbefore := len(p.result.References)\n\t\tif err = p.attributeView(view, apicontract.AssetReference{AvID: id, Path: \"storage/av/\" + entry.Name()}); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif len(p.result.References) > before {\n\t\t\tp.files = append(p.files, &assetRelinkFile{path: abs, before: data, view: view, items: p.referenceItems(before)})\n\t\t\towners := []apicontract.AssetReference{}\n\t\t\tfor _, tree := range p.trees {","sourceCodeStart":297,"sourceCodeEnd":333,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/model/asset_relink.go#L297-L333","documentation":"Each storage/av/<id>.json file must be valid JSON. If json.Valid(data) fails, the definition is corrupted and the relink scan aborts — parsing or rewriting references in a malformed definition could destroy database data.","triggerScenarios":"scanViews reads storage/av/<id>.json and the bytes are not valid JSON (truncated write, binary garbage, partial sync, manual edit).","commonSituations":"Disk full during a previous write left a truncated file; a text editor saved the file with BOM/encoding damage; a sync conflict merged two JSON files badly; the file was overwritten by non-JSON content.","solutions":["Restore the file from history/backup or from the synced source","Check disk space and re-trigger an AV index/repair if the app offers one","Delete the corrupt definition only if the AV is unused, then recreate the database block","Validate the file with a JSON linter before restoring to confirm it parses"],"exampleFix":"// before\n// data/storage/av/<id>.json: \"{...truncated\"\n// after\ncp(\"history/2026-01-02-150405-replace/storage/av/<id>.json\", \"data/storage/av/<id>.json\")","handlingStrategy":"validation","validationCode":"// validate every AV definition parses before relinking\nfor _, f := range avFiles {\n\tdata, _ := os.ReadFile(f)\n\tif !json.Valid(data) {\n\t\t// restore from history/backup before relink\n\t}\n}","typeGuard":null,"tryCatchPattern":"// catch and recover\nif err := plan.Scan(); err != nil {\n\tif strings.Contains(err.Error(), \"invalid attribute view JSON\") {\n\t\t// restore the named file from history, then retry\n\t}\n\treturn err\n}","preventionTips":["Avoid killing the kernel during AV writes; ensure adequate disk space","Do not hand-edit storage/av/*.json","Verify JSON validity after restoring files from backups"],"tags":["json","corruption","attribute-view","storage"],"backgroundTag":"json-parse-error","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"}