siyuan-note/siyuan · error
read file annotation
Error message
read file annotation [%s]: %w
What it means
After resolving the annotation asset, the kernel reads the sibling .sya annotation sidecar file with os.ReadFile. Any OS-level read failure (missing file, permission denied, path too long) is wrapped as this error and aborts the annotation export, keeping the source file untouched.
Solutions
- Check that a .sya file with the exact same name as the PDF exists next to it in assets/
- Fix filesystem permissions on the assets directory so the kernel process can read it
- Re-sync the notebook so the missing .sya sidecar is restored
- Recreate the annotation if the sidecar is permanently lost
Example fix
// before assets/report.pdf (no sidecar) // after assets/report.pdf assets/report.pdf.sya (restored via sync or re-created annotation)
Defensive patterns
Strategy: try-catch
Try / catch
try {
await exportAnnotation(docID);
} catch (e) {
if (/read file annotation/.test(e.message)) {
// re-sync the notebook, then retry once
await syncNotebook(boxID);
return exportAnnotation(docID);
}
throw e;
} Prevention
- Ensure .sya sidecars are included in backups and sync (not excluded patterns)
- Fix workspace directory permissions so the kernel can read assets/
- Watch for case-sensitivity mismatches when moving data between OS filesystems
When it happens
Trigger: Exporting a file annotation whose <asset>.sya sidecar does not exist next to the PDF, or is unreadable due to filesystem permissions, sync placeholder files, or disk errors.
Common situations: PDF annotated elsewhere but the .sya file never synced; the sidecar was cleaned up by a sync tool; read-only mount or permission issue in the workspace data folder; case-sensitivity mismatch on Linux mounts.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- decrypt file annotation
- invalid file annotation reference
- missing or invalid annotation
- parse file annotation
- resolve file annotation asset
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/bdb26d280f30a262.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/export.go:4374
if err != nil {
return fmt.Errorf("resolve file annotation asset [%s]: %w", assetLink, err)
}
sya := absPath + ".sya"
// 以实际资源所属笔记本认证标注密文,读取失败时保留源文件并中止导出。
assetBoxID := ExtractBoxIDFromAssetsPath(absPath)
var dek []byte
if IsEncryptedBox(assetBoxID) {
HoldBoxReadLock(assetBoxID)
defer ReleaseBoxReadLock(assetBoxID)
dek, err = GetDEKIfUnlocked(assetBoxID)
if err != nil {
return err
}
defer clear(dek)
}
syaData, readErr := os.ReadFile(sya)
if readErr != nil {
return fmt.Errorf("read file annotation [%s]: %w", sya, readErr)
}
if nil != dek {
plain, decErr := DecryptAsset(assetBoxID, filepath.Base(sya), dek, syaData)
if decErr != nil {
return fmt.Errorf("decrypt file annotation [%s]: %w", sya, decErr)
}
syaData = plain
}
syaJSON := map[string]struct {
Pages []struct {
Index *int `json:"index"`
} `json:"pages"`
Page *int `json:"page"`
}{}
if err = gulu.JSON.UnmarshalJSON(syaData, &syaJSON); err != nil {
return fmt.Errorf("parse file annotation [%s]: %w", sya, err)
}
annotationData, found := syaJSON[annotationID]View on GitHub (pinned to 9f775e8a12)