Skip to content

[Bug]: Archived tasks can remain on Google Calendar and orphan their event ID #1695

Description

@martin-forge

Bug Description

I hit an issue with Google Calendar export + auto-archive.

Summary

When a scheduled task is marked done and later auto-archived, the TaskNote can be moved into TaskNotes/Archive but its Google Calendar event can remain visible.

In some cases the archived note still contains googleCalendarEventId. In worse cases, the note loses googleCalendarEventId even though the Google event still exists, which makes the remote event effectively orphaned because there is no local event ID left for retry/cleanup.

Environment

  • TaskNotes 4.4.0
  • Obsidian desktop on macOS
  • Google Calendar export enabled
  • syncOnTaskComplete: true
  • syncOnTaskDelete: true
  • syncTrigger: scheduled
  • done status configured with autoArchive: true

Steps to reproduce

  1. Enable Google Calendar export.
  2. Create a scheduled task so it syncs to Google Calendar and receives a googleCalendarEventId.
  3. Mark the task done.
  4. Wait for auto-archive to move it into TaskNotes/Archive.
  5. Check Google Calendar and the archived note frontmatter.

Expected behavior

  • Once the task is archived, the Google Calendar event should be deleted.
  • googleCalendarEventId should only be removed from the note after the delete succeeds, or if Google returns 404/410 because the event is already gone.

Actual behavior

  • The task can be archived successfully while the Google Calendar event remains visible.
  • Sometimes the archived note still contains googleCalendarEventId.
  • Sometimes googleCalendarEventId is removed even though the Google event still exists, so the local pointer needed to retry deletion is lost.

Suspected cause

There seem to be two related issues in the current implementation.

1. Archive-time delete is fire-and-forget

In src/services/TaskService.ts around lines 1086-1093, toggleArchive() does this:

  • checks whether the task is being archived
  • calls deleteTaskFromCalendar(updatedTask).catch(...)
  • does not await it

That means the archive operation can succeed even if calendar deletion fails or never completes.

2. Event ID is always cleared even after real delete failures

In src/services/TaskCalendarSyncService.ts around lines 919-945, deleteTaskFromCalendar():

  • attempts to delete the Google event
  • logs non-404/410 failures
  • then still calls removeTaskEventId(task.path) unconditionally

That means a real delete failure can still clear the local googleCalendarEventId, leaving the Google event behind with no local reference to clean it up later.

Why this matters

This creates a bad failure mode:

  1. task is marked done
  2. auto-archive runs
  3. task moves into TaskNotes/Archive
  4. Google Calendar event is not deleted
  5. local googleCalendarEventId may already be gone

At that point the archive state and calendar state are inconsistent.

Suggested fix

I think the archive path should be made transactional / retry-safe:

  • await archive-time deleteTaskFromCalendar() in toggleArchive()
  • only remove googleCalendarEventId after:
    • successful delete, or
    • 404 / 410 from Google
  • if needed, preserve the pre-archive event ID across the archive move so the delete step still has the ID even if refreshed task data drops it

Additional note

I tested a local patch that:

  • awaited archive-time deletion
  • retried deletion
  • avoided clearing googleCalendarEventId after arbitrary delete failures

That resolved the issue in my local testing.

Happy to test a fix if helpful.

Activity

  1. martin-forge commented on Mar 16, 2026

    @martin-forge
    ContributorAuthor

    I’ve now validated a local source-level fix for this in 4.4.0.

    What fixed it locally:

    • make archive-time Google Calendar cleanup awaited in toggleArchive() instead of fire-and-forget
    • make deleteTaskFromCalendar() return success/failure and only clear local Google metadata after a confirmed delete (or a 404/410)
    • preserve the pre-archive Google event IDs across the archive/move step so the delete still has the IDs it needs
    • if local archive succeeds but Google deletion still fails, keep retrying cleanup from the auto-archive queue until it succeeds

    I also added regression coverage for:

    • archive + successful Google deletion
    • repeated deletion failure preserving metadata for retry
    • auto-archive retrying cleanup for already-archived tasks with lingering Google links

    So this now looks like a concrete plugin-level fix rather than a vault/config issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions