open-webui/open-webui · warning · HTTPException

Default calendar cannot be deleted

Error message

Default calendar cannot be deleted

What it means

DELETE /api/v1/calendars/{calendar_id}/delete: the calendar exists and the requester is owner/admin, but cal.is_default is true. Each user's default calendar cannot be deleted; it must first be demoted by setting another calendar as default (POST /{calendar_id}/default).

Source

Thrown at backend/open_webui/routers/calendar.py:451


@router.delete('/{calendar_id}/delete')
async def delete_calendar(request: Request, calendar_id: str, user: UserModel = Depends(get_verified_user)):
    await check_calendar_permission(request, user)

    # Block deletion of the virtual Scheduled Tasks calendar
    if calendar_id == SCHEDULED_TASKS_CALENDAR_ID:
        raise HTTPException(status_code=400, detail='System calendars cannot be deleted')

    cal = await _check_calendar_access(calendar_id, user, 'write')

    # Only owner/admin can delete
    if cal.user_id != user.id and user.role != 'admin':
        raise HTTPException(status_code=403, detail='Only owner can delete calendar')

    # Block deletion of default calendar
    if cal.is_default:
        raise HTTPException(status_code=400, detail='Default calendar cannot be deleted')

    result = await Calendars.delete_calendar_by_id(calendar_id)
    if not result:
        raise HTTPException(status_code=500, detail='Failed to delete')
    await publish_event(
        request,
        EVENTS.CALENDAR_DELETED,
        actor=user,
        subject_id=calendar_id,
        data={'name': cal.name},
    )
    return {'status': True}


@router.post('/{calendar_id}/default')
async def set_default_calendar(request: Request, calendar_id: str, user: UserModel = Depends(get_verified_user)):
    await check_calendar_permission(request, user)
    cal = await Calendars.set_default_calendar(user.id, calendar_id)

View on GitHub (pinned to 01f4282f1f)

Solutions

  1. Create or pick another calendar, then POST /api/v1/calendars/{other_id}/default to transfer the default flag.
  2. Retry the delete on the former default calendar.
  3. In bulk-delete flows, skip is_default calendars or reorder operations so a new default is set first.

Example fix

// before
await api.delete(`/calendars/${id}/delete`);
// after
if (calendar.is_default) {
  await api.post(`/calendars/${otherId}/default`);
}
await api.delete(`/calendars/${id}/delete`);
Defensive patterns

Strategy: validation

Validate before calling

if (calendar.is_default) {
  const fallback = calendars.find(c => c.id !== calendar.id && c.user_id === currentUser.id);
  if (!fallback) throw new Error('Create another calendar before deleting the default');
  await api.post(`/api/v1/calendars/${fallback.id}/default`);
}
await api.delete(`/api/v1/calendars/${calendar.id}/delete`);

Type guard

function isDefaultCalendar(c: { is_default?: boolean } | null | undefined): boolean {
  return !!c?.is_default;
}

Try / catch

try {
  await api.delete(`/api/v1/calendars/${id}/delete`);
} catch (e) {
  if (e?.status === 400 && e?.detail === 'Default calendar cannot be deleted') {
    await promoteAnotherCalendarAndRetry(id);
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: Owner deletes their only remaining calendar (which is the default); deleting the auto-created default calendar without first creating/promoting another; bulk delete that includes the default calendar id.

Common situations: New users cleaning up initial calendars; scripts pruning all calendars; UI not surfacing which calendar is default.

Related errors


AI-assisted analysis of open-webui/open-webui@01f4282f1f (2026-08-14). Data as JSON: /api/errors/37e197c165b0c44d. Report an issue: GitHub.