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

  1. Append the vCard extension to the resource name: build paths as <bookPath>/<uid>.vcf (use the VCardFileExt constant, not a literal)
  2. Validate the filename extension before issuing the request; reject non-.vcf names client-side
  3. If the data was imported with the wrong extension, rename the card files to *.vcf and re-import via ImportAddressBook
  4. 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

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


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)