Skip to content

"TemplateSyntaxError: Could not parse the remainder" when sending email with triple curly braces #478

@JestemStefan

Description

@JestemStefan

Steps to recreate

from django.core.mail import mail_admins
mail_admins("TEST ", "{{{TEST}}}")


>>> TemplateSyntaxError: Could not parse the remainder: '{TEST' from '{TEST'

In my app I'm sending some string and it's required that it will be inside triple curly braces like this

some_str = "{{{TEST}}}"

When error is raised for whatever reason, mail_admins is triggered and since stacktrace contains some_str it throws

TemplateSyntaxError: Could not parse the remainder: '{TEST' from '{TEST'

This error is raised, because post_office puts my message into Template and tries to render it, but this is not my intention.
I want to send it as is.
I cannot escape it or other service will not accept it

Error trace:

In [1]: from django.core.mail import mail_admins

In [2]: mail_admins("TEST ", "{{{TEST}}}")
---------------------------------------------------------------------------
TemplateSyntaxError                       Traceback (most recent call last)
Cell In[2], line 1
----> 1 mail_admins("TEST ", "{{{TEST}}}")

File /usr/local/lib/python3.12/site-packages/django/core/mail/__init__.py:134, in mail_admins(subject, message, fail_silently, connection, html_message)
    132 if html_message:
    133     mail.attach_alternative(html_message, "text/html")
--> 134 mail.send(fail_silently=fail_silently)

File /usr/local/lib/python3.12/site-packages/django/core/mail/message.py:299, in EmailMessage.send(self, fail_silently)
    295 if not self.recipients():
    296     # Don't bother creating the network connection if there's nobody to
    297     # send to.
    298     return 0
--> 299 return self.get_connection(fail_silently).send_messages([self])

File /usr/local/lib/python3.12/site-packages/post_office/backends.py:56, in EmailBackend.send_messages(self, email_messages)
     53     else:
     54         attachment_files[attachment[0]] = ContentFile(attachment[1])
---> 56 email = create(
     57     sender=from_email,
     58     recipients=email_message.to,
     59     cc=email_message.cc,
     60     bcc=email_message.bcc,
     61     subject=subject,
     62     message=message,
     63     html_message=html_body,
     64     headers=headers,
     65 )
     67 if attachment_files:
     68     attachments = create_attachments(attachment_files)

File /usr/local/lib/python3.12/site-packages/post_office/mail.py:101, in create(sender, recipients, cc, bcc, subject, message, html_message, context, scheduled_time, expires_at, headers, template, priority, render_on_delivery, commit, backend)
     99 _context = Context(context or {})
    100 subject = Template(subject).render(_context)
--> 101 message = Template(message).render(_context)
    102 html_message = Template(html_message).render(_context)
    104 email = Email(
    105     from_email=sender,
    106     to=recipients,
   (...)
    119     template=template,
    120 )

File /usr/local/lib/python3.12/site-packages/django/template/base.py:154, in Template.__init__(self, template_string, origin, name, engine)
    152 self.engine = engine
    153 self.source = str(template_string)  # May be lazy.
--> 154 self.nodelist = self.compile_nodelist()

File /usr/local/lib/python3.12/site-packages/django/template/base.py:200, in Template.compile_nodelist(self)
    192 parser = Parser(
    193     tokens,
    194     self.engine.template_libraries,
    195     self.engine.template_builtins,
    196     self.origin,
    197 )
    199 try:
--> 200     return parser.parse()
    201 except Exception as e:
    202     if self.engine.debug:

File /usr/local/lib/python3.12/site-packages/django/template/base.py:484, in Parser.parse(self, parse_until)
    482     filter_expression = self.compile_filter(token.contents)
    483 except TemplateSyntaxError as e:
--> 484     raise self.error(token, e)
    485 var_node = VariableNode(filter_expression)
    486 self.extend_nodelist(nodelist, var_node, token)

File /usr/local/lib/python3.12/site-packages/django/template/base.py:482, in Parser.parse(self, parse_until)
    478     raise self.error(
    479         token, "Empty variable tag on line %d" % token.lineno
    480     )
    481 try:
--> 482     filter_expression = self.compile_filter(token.contents)
    483 except TemplateSyntaxError as e:
    484     raise self.error(token, e)

File /usr/local/lib/python3.12/site-packages/django/template/base.py:600, in Parser.compile_filter(self, token)
    596 def compile_filter(self, token):
    597     """
    598     Convenient wrapper for FilterExpression
    599     """
--> 600     return FilterExpression(token, self)

File /usr/local/lib/python3.12/site-packages/django/template/base.py:703, in FilterExpression.__init__(self, token, parser)
    701     upto = match.end()
    702 if upto != len(token):
--> 703     raise TemplateSyntaxError(
    704         "Could not parse the remainder: '%s' "
    705         "from '%s'" % (token[upto:], token)
    706     )
    708 self.filters = filters
    709 self.var = var_obj

TemplateSyntaxError: Could not parse the remainder: '{TEST' from '{TEST'

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions