[bug]: Issue-update emails show broken "None" / raw TipTap comment boxes
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:
- Literal
Nonetext boxes (from deleted comments) - Short status-like text such as
UPDATEin plain white boxes that look like form controls - 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:
delete_comment_activitycreates an activity withfield=comment,verb=deleted, and nonew_value/old_value(they stay SQLNULL).notification_taskserializes withstr(issue_activity.get("new_value"))→ the Python string"None".create_payloadinemail_notification_tasktreats any truthy string as content, so"None"is appended tocomment.new_value.- 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.
- 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
- Enable email notifications for issue comments
- Add a short comment on an issue (e.g.
UPDATE) - Immediately delete that comment (or delete any comment so a deleted activity is logged)
- Wait for the stacked issue-update email
- 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.pyapps/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
|safecomment 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=deletedcomment/mention activities increate_payload - filter empty /
"None"values - process comment HTML for email (mentions + image/embed placeholders)
- unit test reproducing the EQA-6 payload shape
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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