Skip to content

fix(stickies): restore full state on failed delete#9064

Open
DavidIMk wants to merge 2 commits into
makeplane:previewfrom
DavidIMk:fix/sticky-delete-rollback
Open

fix(stickies): restore full state on failed delete#9064
DavidIMk wants to merge 2 commits into
makeplane:previewfrom
DavidIMk:fix/sticky-delete-rollback

Conversation

@DavidIMk
Copy link
Copy Markdown

@DavidIMk DavidIMk commented May 13, 2026

When deleting a sticky note fails (e.g. network error), the frontend performs a partial rollback. This leaves
the sticky invisible in the list even though its data still exists in memory. The sticky only reappears after a full page reload.
Additionally, the success toast ("Sticky has been successfully removed") was still shown even when the API call failed, because the store swallowed the error instead of re-throwing it.

I've also added a trailing slash to the deleteSticky and getSticky API paths to avoid an unneeded 301 redirect

  • Add trailing slash to getSticky and deleteSticky API paths, fixing unnecessary 301 redirect
  • Snapshot workspaceStickies, activeStickyId, and recentStickyId before optimistic delete so all three are restored if the API call fails
  • Re-throw the error so callers show an error toast instead of success

Fixes #9050

Description

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • Feature (non-breaking change which adds functionality)
  • Improvement (change that would cause existing functionality to not work as expected)
  • Code refactoring
  • Performance improvements
  • Documentation update

Screenshots and Media (if applicable)

Test Scenarios

References

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Improved sticky deletion reliability: app state now fully restores if a deletion operation fails.
    • Enhanced error handling for sticky updates: original error details are preserved for clearer troubleshooting.

Review Change Stack

Review Change Stack

- Add trailing slash to getSticky and deleteSticky API paths, fixing unnecessary 301 redirect
- Snapshot workspaceStickies, activeStickyId, and recentStickyId before
  optimistic delete so all three are restored if the API call fails
- Re-throw the error so callers show an error toast instead of success

Fixes makeplane#9050
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 13, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3f35e26d-e678-4dc0-a27d-252e4b7d9f47

📥 Commits

Reviewing files that changed from the base of the PR and between 81662df and 082dd65.

📒 Files selected for processing (1)
  • apps/web/core/store/sticky/sticky.store.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web/core/store/sticky/sticky.store.ts

📝 Walkthrough

Walkthrough

This PR fixes deleted stickies reappearing after reload by adding trailing slashes to sticky service endpoints and by snapshotting/restoring relevant store state and re-throwing original errors on update/delete failures.

Changes

Sticky Deletion Fix

Layer / File(s) Summary
API endpoint alignment
apps/web/core/services/sticky.service.ts
getSticky and deleteSticky request URLs now include a trailing slash (/stickies/${id}/).
Error handling with state restoration
apps/web/core/store/sticky/sticky.store.ts
updateSticky restores prior stickies[id] and re-throws the original error. deleteSticky snapshots workspaceStickies[workspaceSlug], activeStickyId, and recentStickyId before mutating; on failure it restores those snapshots along with stickies[id] and re-throws the error.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I nudged the slash where it belonged,
Restored the notes once something went wrong,
State kept safe, errors passed through,
No more ghosts returning to view,
Hop, patch, and hop—this bug is gone!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: fixing state restoration on a failed sticky deletion operation.
Description check ✅ Passed The description includes the motivation, implementation details (trailing slash, state snapshots, error re-throwing), and marks the PR as a bug fix with reference to issue #9050.
Linked Issues check ✅ Passed The PR addresses issue #9050 by ensuring sticky deletion persists correctly and error handling displays appropriate toasts instead of false success messages.
Out of Scope Changes check ✅ Passed All changes align with fixing the sticky deletion issue: API path fixes, state snapshot restoration logic, and error re-throwing are all within scope of resolving #9050.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/web/core/store/sticky/sticky.store.ts (1)

193-208: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

updateSticky rollback uses a mutated reference, so failed updates are not actually reverted.

Line 194 stores a reference to this.stickies[id]; Line 200 mutates that same object. On failure, Line 207 reassigns already-mutated data.

Suggested fix
   updateSticky = async (workspaceSlug: string, id: string, updates: Partial<TSticky>) => {
     const sticky = this.stickies[id];
     if (!sticky) return;
+    const previousSticky = structuredClone(sticky);
     try {
       runInAction(() => {
         Object.keys(updates).forEach((key) => {
           const currentStickyKey = key as keyof TSticky;
           set(this.stickies[id], key, updates[currentStickyKey] || undefined);
         });
       });
       this.recentStickyId = id;
       await this.stickyService.updateSticky(workspaceSlug, id, updates);
     } catch (error) {
       console.error("Error in updating sticky:", error);
-      this.stickies[id] = sticky;
+      this.stickies[id] = previousSticky;
       throw error;
     }
   };
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/web/core/store/sticky/sticky.store.ts` around lines 193 - 208, In
updateSticky, the rollback currently reassigns the same mutated object because
sticky = this.stickies[id] is a reference; fix by making a deep copy of the
original sticky (e.g., use structuredClone or cloneDeep) before runInAction and
mutations, then on catch restore this.stickies[id] = originalCopy; ensure you
copy before calling set(...) inside updateSticky so the restore returns the
pre-update state.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/web/core/store/sticky/sticky.store.ts`:
- Around line 215-220: The deleteSticky logic can throw when
workspaceStickies[workspaceSlug] is undefined; update the code in deleteSticky
to safely default to an empty array before filtering and when taking the backup:
set previousWorkspaceStickies using (this.workspaceStickies[workspaceSlug] ||
[]) and perform the delete with this.workspaceStickies[workspaceSlug] =
(this.workspaceStickies[workspaceSlug] || []).filter(stickyId => stickyId !==
id); keep previousActiveStickyId and previousRecentStickyId unchanged and ensure
the same safe fallback is used anywhere else in deleteSticky that reads
workspaceStickies[workspaceSlug].

---

Outside diff comments:
In `@apps/web/core/store/sticky/sticky.store.ts`:
- Around line 193-208: In updateSticky, the rollback currently reassigns the
same mutated object because sticky = this.stickies[id] is a reference; fix by
making a deep copy of the original sticky (e.g., use structuredClone or
cloneDeep) before runInAction and mutations, then on catch restore
this.stickies[id] = originalCopy; ensure you copy before calling set(...) inside
updateSticky so the restore returns the pre-update state.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: dd37e238-5dbe-46d2-b6f1-dcd579b5427f

📥 Commits

Reviewing files that changed from the base of the PR and between 4225bc5 and 81662df.

📒 Files selected for processing (2)
  • apps/web/core/services/sticky.service.ts
  • apps/web/core/store/sticky/sticky.store.ts

Comment thread apps/web/core/store/sticky/sticky.store.ts Outdated
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented May 14, 2026

CLA assistant check
All committers have signed the CLA.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bug]: Deleted Stickies reappear on page reload

2 participants