siyuan-note/siyuan · error

CardDAV: path is invalid

Error message

CardDAV: path is invalid

What it means

ErrorCardDavPathInvalid is a sentinel error returned by Contacts.QueryAddressObjects (kernel/model/carddav.go:484) when the queried CardDAV URL's path depth does not correspond to any known resource type (root, principals, user principal, home set, address book, or address). It is the catch-all 'this URL is not a valid CardDAV resource' error, distinct from the more specific book/address errors.

Source

Thrown at kernel/model/carddav.go:91

		},
	}

	defaultAddressBook = carddav.AddressBook{
		Path:                 CardDavDefaultAddressBookPath,
		Name:                 CardDavDefaultAddressBookName,
		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)

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Print GetCardDavPathDepth(urlPath) and compare against the constant hierarchy: /carddav (1), /carddav/principals (2), /carddav/principals/main (3), /carddav/principals/main/contacts (4), .../contacts/<book> (5), .../contacts/<book>/<id>.vcf (6).
  2. Fix the client's address-book base URL so it matches CardDavHomeSetPath (/carddav/principals/main/contacts) or one of its sub-resources.
  3. Remove extraneous segments (nesting below an address, metadata file names) from the queried path.
  4. Query a listed resource instead: enumerate address books from the home set first and use those exact paths.

Example fix

// before: nested path of depth 7 -> no known resource type
books, err := contacts.QueryAddressObjects("/carddav/principals/main/contacts/default/sub/x.vcf", nil)

// after: query the address book itself
books, err := contacts.QueryAddressObjects("/carddav/principals/main/contacts/default", nil)
Defensive patterns

Strategy: validation

Validate before calling

depth := int(model.GetCardDavPathDepth(urlPath))
if depth < 1 || depth > 6 {
    return fmt.Errorf("CardDAV path depth %d out of range for %s", depth, urlPath)
}

Type guard

func isKnownCardDavResource(p string) bool {
    d := model.GetCardDavPathDepth(p)
    return d >= model.CardDavPathDepth(1) && d <= model.CardDavPathDepth(6)
}

Try / catch

objs, err := contacts.QueryAddressObjects(urlPath, query)
if errors.Is(err, model.ErrorCardDavPathInvalid) {
    log.Printf("unknown CardDAV resource %s (depth %d)", urlPath, model.GetCardDavPathDepth(urlPath))
    return http.StatusNotFound
}

Prevention

When it happens

Trigger: QueryAddressObjects(urlPath, query) receives a path whose GetCardDavPathDepth is not 1..6 of the known /carddav/principals/main/contacts... hierarchy — e.g. a too-deep path (nested segment below an address), an empty or cleaned path resolving to depth 0, or an address-book.json metadata path passed by mistake.

Common situations: A CardDAV client misconfigured with a wrong base URL (extra or missing path segments, trailing garbage, double slashes that clean differently); integration code constructing ad-hoc paths under /carddav; a client pointing at the CalDAV hierarchy paths inside the CardDAV handler.

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@8641553a1f (2026-09-11). Data as JSON: /api/errors/3745aeede8ec6bad. Report an issue: GitHub.