nextcloud/server · warning · Sabre\DAV\Exception\MethodNotAllowed

Renaming calendars is not yet supported

Error message

Renaming calendars is not yet supported

What it means

HTTP 405 MethodNotAllowed thrown from the final ExternalCalendar::setName(), which always throws. ExternalCalendar is the abstract base apps extend to expose app-backed calendars through the CalDAV integration API (ICalendarProvider); its URI always looks like app-generated--<appId>--<calendarUri>. Sabre invokes setName() when a MOVE targets the calendar collection, so renaming any app-registered calendar is rejected by design.

Source

Thrown at apps/dav/lib/CalDAV/Integration/ExternalCalendar.php:68

	/**
	 * @inheritDoc
	 */
	#[\Override]
	final public function getName() {
		return implode(self::DELIMITER, [
			self::PREFIX,
			$this->appId,
			$this->calendarUri,
		]);
	}

	/**
	 * @inheritDoc
	 */
	#[\Override]
	final public function setName($name) {
		throw new DAV\Exception\MethodNotAllowed('Renaming calendars is not yet supported');
	}

	/**
	 * @inheritDoc
	 */
	#[\Override]
	final public function createDirectory($name) {
		throw new DAV\Exception\MethodNotAllowed('Creating collections in calendar objects is not allowed');
	}

	/**
	 * Checks whether the calendar uri is app-generated
	 *
	 * @param string $calendarUri
	 * @return bool
	 */
	public static function isAppGeneratedCalendar(string $calendarUri):bool {
		return str_starts_with($calendarUri, self::PREFIX) && substr_count($calendarUri, self::DELIMITER) >= 2;

View on GitHub (pinned to ecdeb153ff)

Solutions

  1. Rename or reconfigure the calendar inside the app that provides it (its settings UI or API)
  2. Do not issue DAV MOVE on calendars whose URI starts with app-generated--; filter them out of rename flows
  3. If you are the provider app, expose a different calendarUri and let clients re-discover calendars via PROPFIND

Example fix

// before: MOVE any calendar, including app-generated ones -> 405
await davMove(`/remote.php/dav/calendars/${uid}/${calUri}/`, `/remote.php/dav/calendars/${uid}/${newUri}/`);
// after: skip app-generated calendars when renaming
if (calUri.startsWith('app-generated--')) { continue; }
await davMove(`/remote.php/dav/calendars/${uid}/${calUri}/`, `/remote.php/dav/calendars/${uid}/${newUri}/`);
Defensive patterns

Strategy: validation

Validate before calling

// client: filter rename targets
function isRenamableCalendar(calUri) {
  return !calUri.startsWith('app-generated--');
}

Type guard

// PHP (server-side, when iterating DAV nodes)
function isRenamable(\Sabre\DAV\INode $node): bool {
  if ($node instanceof \OCA\DAV\CalDAV\Integration\ExternalCalendar) {
    return false;
  }
  return !str_starts_with($node->getName(), 'app-generated--');
}

Try / catch

try {
  await davMove(src, dst);
} catch (e) {
  if (e.status === 405) { /* rename unsupported for this calendar: surface to user, no retry */ }
  else throw e;
}

Prevention

When it happens

Trigger: A CalDAV client issuing MOVE on /remote.php/dav/calendars/<user>/app-generated--<appId>--<uri>/ — e.g. drag-and-drop rename in a calendar UI, or a sync client's repair pass that tries to normalize calendar names.

Common situations: Users attempting to rename calendars contributed by third-party apps (app store apps that register calendars); automated clients that rename every writable-looking calendar; app updates that changed the exposed calendar URI.

Related errors


AI-assisted analysis of nextcloud/server@ecdeb153ff (2026-08-17). Data as JSON: /api/errors/1f781dca20fe293e. Report an issue: GitHub.