siyuan-note/siyuan · error
invalid file annotation reference
Error message
invalid file annotation reference [%s]
What it means
processFileAnnotationRef parses a file-annotation reference of the form produced by util.SplitFileAnnotationRef. If the refID does not contain a valid annotation ID portion (empty after splitting), the reference is malformed and the export fails with 'invalid file annotation reference [%s]'.
Solutions
- Fix or remove the malformed file annotation reference in the source document (re-insert the annotation from the PDF asset)
- Check the refID format: it must be '<assetPath>@<annotationID>'; regenerate the link via the UI's file annotation feature
- If encountered in bulk, validate all file-annotation-ref attributes in the notebook and repair or strip invalid ones
Example fix
// before <span data-type="file-annotation-ref" data-id="assets/paper.pdf@">text</span> // empty annotation id // after <span data-type="file-annotation-ref" data-id="assets/paper.pdf@page=2&loc=...">text</span>
Defensive patterns
Strategy: type-guard
Validate before calling
function isValidFileAnnotationRef(refId) {
const idx = refId.indexOf('@');
return idx > 0 && refId.slice(idx + 1).length > 0;
} Type guard
const hasAnnotationID = ref => typeof ref === 'string' && ref.split('@').length === 2 && ref.split('@')[1] !== ''; Try / catch
try { await exportPDF(id); }
catch (e) {
const m = String(e).match(/invalid file annotation reference \[(.+)\]/);
if (m) { repairOrRemoveAnnotationRef(m[1]); await retryExport(); }
} Prevention
- Never hand-edit data-id attributes of file-annotation-ref spans
- Re-create broken annotations from the PDF asset via the UI instead of patching raw text
- Validate notebook content for malformed annotation refs before batch exports
When it happens
Trigger: Export (PDF/annotation processing) encounters a node whose file-annotation-ref attribute holds a string that splits into an empty annotationID — e.g. truncated, hand-edited, or plugin-written refID without the '@'-separated annotation id part.
Common situations: Document content edited by an older/plugin version writing malformed annotation refs; PDF asset replaced so annotation links got corrupted; manual editing of .sy content breaking the ref format.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- missing or invalid annotation
- resolve file annotation asset
- decrypt file annotation
- parse file annotation
- read file annotation
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/9283f59ac8b96f82.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/export.go:4341
if n.ID == id {
ret = true
return ast.WalkStop
}
return ast.WalkContinue
})
return
}
type refAsFootnotes struct {
refNum string
refAnchorText string
}
func processFileAnnotationRef(refID string, n *ast.Node, fileAnnotationRefMode int, boxID string) error {
assetLink, annotationID := util.SplitFileAnnotationRef(refID)
if "" == annotationID {
return fmt.Errorf("invalid file annotation reference [%s]", refID)
}
p, query, _ := splitAssetReference(assetLink)
assetLink = p
if "" != query {
assetLink += "?" + query
}
lookupLink := p
if decodedPath, decodeErr := url.PathUnescape(p); nil == decodeErr {
lookupLink = decodedPath
}
if "" != query {
lookupLink += "?" + query
}
absPath, err := GetAssetAbsPathInBox(lookupLink, boxID)
if err != nil {
return fmt.Errorf("resolve file annotation asset [%s]: %w", assetLink, err)
}
sya := absPath + ".sya"View on GitHub (pinned to 9f775e8a12)