makeplane / makeplane/plane

[bug]: Issue-update emails show broken "None" / raw TipTap comment boxes

Open
#9,523 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
59.6k
Forks
5.8k
Avg merge
1d 22h
Merged PRs (30d)
49

Description

Is there an existing issue for this?
  • I have searched the existing issues
Current behavior

Issue-update notification emails often render a Comments section that looks broken and unprofessional:

  1. Literal None text boxes (from deleted comments)
  2. Short status-like text such as UPDATE in plain white boxes that look like form controls
  3. Raw TipTap custom elements (mention-component, image-component) that email clients cannot render

Screenshot description: EQA-6 updates email → Comments shows two white boxes labeled UPDATE and None under the actor name, instead of a real comment body.

Root cause

Confirmed on self-hosted CE against production activity/email logs:

  1. delete_comment_activity creates an activity with field=comment, verb=deleted, and no new_value/old_value (they stay SQL NULL).
  2. notification_task serializes with str(issue_activity.get("new_value")) → the Python string "None".
  3. create_payload in email_notification_task treats any truthy string as content, so "None" is appended to comment.new_value.
  4. When a comment is created and quickly deleted (or batched in the same email window), the email template iterates:
{% for actor_comment in comment.actor_comments.new_value %}
  <p> {{ actor_comment|safe }} </p>
{% endfor %}

and renders both the real HTML and the literal None.

  1. Separately, only mentions were run through process_html_content; regular comments were injected raw, so TipTap nodes never convert for email clients.

Reproduced payload (EQA-6, sent 2026-08-01 13:05 UTC):

{
  "comment": {
    "old_value": ["None"],
    "new_value": [
      "<p ...><strong>UPDATE</strong></p>",
      "None"
    ]
  }
}
Expected behavior
  • Deleted comments must not appear as None (or at all) in email bodies
  • Comments in email should show readable text (mentions as @name, images as a placeholder)
  • Empty create/delete-only batches should not send a content-less “Comments” email
Steps to reproduce
  1. Enable email notifications for issue comments
  2. Add a short comment on an issue (e.g. UPDATE)
  3. Immediately delete that comment (or delete any comment so a deleted activity is logged)
  4. Wait for the stacked issue-update email
  5. Observe Comments section: boxes with the comment text and/or None
Environment
  • Plane CE self-hosted (v1.3.x / current preview)
  • apps/api/plane/bgtasks/email_notification_task.py
  • apps/api/plane/bgtasks/notification_task.py
  • Template: apps/api/templates/emails/notifications/issue-updates.html ({{ actor_comment|safe }})
Related
  • #9218 — Stored XSS via the same |safe comment path (security; complementary)
  • #8673 — poor TEXT multipart alternative (related quality)
Anything else?

Happy to open a PR with:

  • str(None)"" when building email logs
  • skip verb=deleted comment/mention activities in create_payload
  • filter empty / "None" values
  • process comment HTML for email (mentions + image/embed placeholders)
  • unit test reproducing the EQA-6 payload shape

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with apps/api/plane/bgtasks/notification_task.py and email_notification_task.py, then inspect apps/api/templates/emails/notifications/issue-updates.html and reproduce the EQA-6 payload shape. Add a unit test covering deleted and TipTap comment content. Done means deleted or empty comments do not produce a Comments section, while remaining comments render readable mentions and image placeholders.

Written by the indexing model from the issue text.

Assessment

Tech stack
django, python
Domain
api, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
65/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.