siyuan-note/siyuan · error
CardDAV: address file extension name is invalid
Error message
CardDAV: address file extension name is invalid
What it means
CardDAV: address file extension name is invalid is declared at kernel/model/carddav.go:99 and returned by ParseAddressPath when the final path segment does not carry the required vCard extension (VCardFileExt, i.e. .vcf). CardDAV address objects are stored one-per-file as vCards, so any other extension is rejected before the path is resolved. The check runs at carddav.go:141 after the extension is extracted from the parsed path.
Solutions
- Append the vCard extension to the resource name: build paths as <bookPath>/<uid>.vcf (use the VCardFileExt constant, not a literal)
- Validate the filename extension before issuing the request; reject non-.vcf names client-side
- If the data was imported with the wrong extension, rename the card files to *.vcf and re-import via ImportAddressBook
- Map this sentinel to HTTP 400/404 in the CardDAV handler instead of surfacing it as an internal error
Example fix
// before path := addressBookPath + "/" + uid // after path := addressBookPath + "/" + uid + VCardFileExt // "card.vcf"
Defensive patterns
Strategy: validation
Validate before calling
if filepath.Ext(name) != VCardFileExt {
return fmt.Errorf("address %q must end in .vcf", name)
} Prevention
- Build card paths with the VCardFileExt constant instead of string literals
- Validate filenames at import time so bad extensions never enter the store
When it happens
Trigger: Parsing or requesting an address object path whose file component lacks .vcf — e.g. a PUT/GET/DELETE to a CardDAV URL ending in .json, .txt, or no extension; constructing address paths programmatically without appending VCardFileExt.
Common situations: Hand-written CardDAV client URLs; migration tools that copy contacts as generic files; code that builds resource paths from a card UID but forgets the extension; webdav clients normalizing extensions to lowercase/uppercase mismatch if the constant check is case-sensitive.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- CardDAV: address book path is invalid
- CardDAV: path is invalid
- Conf.Language(79)
- template source must use the .md extension
- 106
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/d086b9f39ca1542d.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/carddav.go:99
Description: "Default address book",
MaxResourceSize: addressBookMaxResourceSize,
SupportedAddressData: addressBookSupportedAddressData,
}
contacts = Contacts{
loaded: false,
changed: false,
lock: sync.Mutex{},
books: sync.Map{},
booksMetaData: []*carddav.AddressBook{},
}
ErrorCardDavPathInvalid = errors.New("CardDAV: path is invalid")
ErrorCardDavBookNotFound = errors.New("CardDAV: address book not found")
ErrorCardDavBookPathInvalid = errors.New("CardDAV: address book path is invalid")
ErrorCardDavAddressNotFound = errors.New("CardDAV: address not found")
ErrorCardDavAddressFileExtensionNameInvalid = errors.New("CardDAV: address file extension name is invalid")
)
// ImportAddressBook imports an address book from a vCard file (*.vcf)
func ImportAddressBook(addressBookPath, cardContent string) (addresses []*AddressObject, err error) {
// TODO: Check whether the path is valid (PathDepth: Address)
// TODO: Check whether the address book exists
// TODO: Decode the card content
// TODO: Save the cards to the file system
return
}
// ExportAddressBook exports an address book to a vCard file (*.vcf)
func ExportAddressBook(addressBookPath string) (cardContent string, err error) {
// TODO: Check whether the path is valid (PathDepth: AddressBook)
// TODO: Check whether the address book exists
// TODO: Encode the card content
return
}View on GitHub (pinned to 9f775e8a12)