Error while sending bulk emails: LazyStaticAbsoluteUrl is not JSON serializable

Hi,

Tutor version: 12.1.7

Has anyone encountered the following error while trying to send a bulk email ? To activate the functionality I followed the steps from this track: How to send mass emails in Open edX? - #14 by RonanFR - Educators - Open edX discussions (I also reported the error there).

lms-worker_1     | Traceback (most recent call last):
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/serialization.py", line 50, in _reraise_errors
lms-worker_1     |     yield
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/serialization.py", line 221, in dumps
lms-worker_1     |     payload = encoder(data)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/utils/json.py", line 69, in dumps
lms-worker_1     |     return _dumps(s, cls=cls or _default_encoder,
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/__init__.py", line 398, in dumps
lms-worker_1     |     return cls(
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/encoder.py", line 296, in encode
lms-worker_1     |     chunks = self.iterencode(o, _one_shot=True)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/encoder.py", line 378, in iterencode
lms-worker_1     |     return _iterencode(o, 0)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/utils/json.py", line 59, in default
lms-worker_1     |     return super(JSONEncoder, self).default(o)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/encoder.py", line 272, in default
lms-worker_1     |     raise TypeError('Object of type %s is not JSON serializable' %
lms-worker_1     | TypeError: Object of type LazyStaticAbsoluteUrl is not JSON serializable
lms-worker_1     | 
lms-worker_1     | During handling of the above exception, another exception occurred:
lms-worker_1     | 
lms-worker_1     | Traceback (most recent call last):
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/celery/app/trace.py", line 412, in trace_task
lms-worker_1     |     R = retval = fun(*args, **kwargs)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/celery/app/trace.py", line 704, in __protected_call__
lms-worker_1     |     return self.run(*args, **kwargs)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/edx_django_utils/monitoring/internal/code_owner/utils.py", line 179, in new_function
lms-worker_1     |     return wrapped_function(*args, **kwargs)
lms-worker_1     |   File "/openedx/edx-platform/lms/djangoapps/instructor_task/tasks.py", line 164, in send_bulk_course_email
lms-worker_1     |     return run_main_task(entry_id, visit_fcn, action_name)
lms-worker_1     |   File "/openedx/edx-platform/lms/djangoapps/instructor_task/tasks_helper/runner.py", line 120, in run_main_task
lms-worker_1     |     task_progress = task_fcn(entry_id, course_id, task_input, action_name)
lms-worker_1     |   File "/openedx/edx-platform/lms/djangoapps/bulk_email/tasks.py", line 221, in perform_delegate_email_batches
lms-worker_1     |     progress = queue_subtasks_for_query(
lms-worker_1     |   File "/openedx/edx-platform/lms/djangoapps/instructor_task/subtasks.py", line 348, in queue_subtasks_for_query
lms-worker_1     |     new_subtask.apply_async()
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/celery/canvas.py", line 235, in apply_async
lms-worker_1     |     return _apply(args, kwargs, **options)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/celery/app/task.py", line 566, in apply_async
lms-worker_1     |     return app.send_task(
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/celery/app/base.py", line 741, in send_task
lms-worker_1     |     amqp.send_task_message(P, name, message, **options)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/celery/app/amqp.py", line 552, in send_task_message
lms-worker_1     |     ret = producer.publish(
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/messaging.py", line 167, in publish
lms-worker_1     |     body, content_type, content_encoding = self._prepare(
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/messaging.py", line 252, in _prepare
lms-worker_1     |     body) = dumps(body, serializer=serializer)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/serialization.py", line 221, in dumps
lms-worker_1     |     payload = encoder(data)
lms-worker_1     |   File "/opt/pyenv/versions/3.8.6/lib/python3.8/contextlib.py", line 131, in __exit__
lms-worker_1     |     self.gen.throw(type, value, traceback)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/serialization.py", line 54, in _reraise_errors
lms-worker_1     |     reraise(wrapper, wrapper(exc), sys.exc_info()[2])
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/vine/five.py", line 194, in reraise
lms-worker_1     |     raise value.with_traceback(tb)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/serialization.py", line 50, in _reraise_errors
lms-worker_1     |     yield
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/serialization.py", line 221, in dumps
lms-worker_1     |     payload = encoder(data)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/utils/json.py", line 69, in dumps
lms-worker_1     |     return _dumps(s, cls=cls or _default_encoder,
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/__init__.py", line 398, in dumps
lms-worker_1     |     return cls(
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/encoder.py", line 296, in encode
lms-worker_1     |     chunks = self.iterencode(o, _one_shot=True)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/encoder.py", line 378, in iterencode
lms-worker_1     |     return _iterencode(o, 0)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/utils/json.py", line 59, in default
lms-worker_1     |     return super(JSONEncoder, self).default(o)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/encoder.py", line 272, in default
lms-worker_1     |     raise TypeError('Object of type %s is not JSON serializable' %
lms-worker_1     | kombu.exceptions.EncodeError: Object of type LazyStaticAbsoluteUrl is not JSON serializable
lms-worker_1     | 2021-11-26 21:51:36,460 ERROR 153 [celery.app.trace] [user None] [ip None] trace.py:255 - Task lms.djangoapps.instructor_task.tasks.send_bulk_course_email[5f935607-b787-4922-ad45-7d924b2527b2] raised unexpected: EncodeError(TypeError('Object of type LazyStaticAbsoluteUrl is not JSON serializable'))
lms-worker_1     | Traceback (most recent call last):
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/serialization.py", line 50, in _reraise_errors
lms-worker_1     |     yield
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/serialization.py", line 221, in dumps
lms-worker_1     |     payload = encoder(data)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/utils/json.py", line 69, in dumps
lms-worker_1     |     return _dumps(s, cls=cls or _default_encoder,
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/__init__.py", line 398, in dumps
lms-worker_1     |     return cls(
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/encoder.py", line 296, in encode
lms-worker_1     |     chunks = self.iterencode(o, _one_shot=True)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/encoder.py", line 378, in iterencode
lms-worker_1     |     return _iterencode(o, 0)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/utils/json.py", line 59, in default
lms-worker_1     |     return super(JSONEncoder, self).default(o)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/encoder.py", line 272, in default
lms-worker_1     |     raise TypeError('Object of type %s is not JSON serializable' %
lms-worker_1     | TypeError: Object of type LazyStaticAbsoluteUrl is not JSON serializable
lms-worker_1     | 
lms-worker_1     | During handling of the above exception, another exception occurred:
lms-worker_1     | 
lms-worker_1     | Traceback (most recent call last):
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/celery/app/trace.py", line 412, in trace_task
lms-worker_1     |     R = retval = fun(*args, **kwargs)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/celery/app/trace.py", line 704, in __protected_call__
lms-worker_1     |     return self.run(*args, **kwargs)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/edx_django_utils/monitoring/internal/code_owner/utils.py", line 179, in new_function
lms-worker_1     |     return wrapped_function(*args, **kwargs)
lms-worker_1     |   File "/openedx/edx-platform/lms/djangoapps/instructor_task/tasks.py", line 164, in send_bulk_course_email
lms-worker_1     |     return run_main_task(entry_id, visit_fcn, action_name)
lms-worker_1     |   File "/openedx/edx-platform/lms/djangoapps/instructor_task/tasks_helper/runner.py", line 120, in run_main_task
lms-worker_1     |     task_progress = task_fcn(entry_id, course_id, task_input, action_name)
lms-worker_1     |   File "/openedx/edx-platform/lms/djangoapps/bulk_email/tasks.py", line 221, in perform_delegate_email_batches
lms-worker_1     |     progress = queue_subtasks_for_query(
lms-worker_1     |   File "/openedx/edx-platform/lms/djangoapps/instructor_task/subtasks.py", line 348, in queue_subtasks_for_query
lms-worker_1     |     new_subtask.apply_async()
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/celery/canvas.py", line 235, in apply_async
lms-worker_1     |     return _apply(args, kwargs, **options)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/celery/app/task.py", line 566, in apply_async
lms-worker_1     |     return app.send_task(
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/celery/app/base.py", line 741, in send_task
lms-worker_1     |     amqp.send_task_message(P, name, message, **options)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/celery/app/amqp.py", line 552, in send_task_message
lms-worker_1     |     ret = producer.publish(
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/messaging.py", line 167, in publish
lms-worker_1     |     body, content_type, content_encoding = self._prepare(
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/messaging.py", line 252, in _prepare
lms-worker_1     |     body) = dumps(body, serializer=serializer)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/serialization.py", line 221, in dumps
lms-worker_1     |     payload = encoder(data)
lms-worker_1     |   File "/opt/pyenv/versions/3.8.6/lib/python3.8/contextlib.py", line 131, in __exit__
lms-worker_1     |     self.gen.throw(type, value, traceback)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/serialization.py", line 54, in _reraise_errors
lms-worker_1     |     reraise(wrapper, wrapper(exc), sys.exc_info()[2])
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/vine/five.py", line 194, in reraise
lms-worker_1     |     raise value.with_traceback(tb)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/serialization.py", line 50, in _reraise_errors
lms-worker_1     |     yield
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/serialization.py", line 221, in dumps
lms-worker_1     |     payload = encoder(data)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/utils/json.py", line 69, in dumps
lms-worker_1     |     return _dumps(s, cls=cls or _default_encoder,
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/__init__.py", line 398, in dumps
lms-worker_1     |     return cls(
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/encoder.py", line 296, in encode
lms-worker_1     |     chunks = self.iterencode(o, _one_shot=True)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/encoder.py", line 378, in iterencode
lms-worker_1     |     return _iterencode(o, 0)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/utils/json.py", line 59, in default
lms-worker_1     |     return super(JSONEncoder, self).default(o)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/encoder.py", line 272, in default
lms-worker_1     |     raise TypeError('Object of type %s is not JSON serializable' %
lms-worker_1     | kombu.exceptions.EncodeError: Object of type LazyStaticAbsoluteUrl is not JSON serializable

Which version of tutor are you running? This issue was fixed a couple months ago in v12.1.3:

Hi Régis,

Thanks for your reply :slight_smile: . The Tutor version is 12.1.7 (mentioned at the beginning of my post :slight_smile: , this is what the command tutor --version displays). I am going to check the post you sent. Thanks!

Sorry about that!

Can you please paste a fuller stacktrace? This looks like a new issue.

But now I think about it the command pip freeze returns tutor-openedx=12.0.1, could that be the issue ? (two versions of tutor installed somehow?)

No, the version that matters is the one printed by tutor --version. You can safely uninstall tutor-openedx, this is just a transition package.

We are going to need more information in order to reproduce the issue. What steps did you follow? What is the asynchronous task that the lms-worker is attempting to run?

Ok, I will reproduce the error and provide a detailed description of the different steps and a fuller stacktrace asap (probably tonight). Thanks!

Hi again,
Below are the steps I followed:

  1. The first thing I did was to connect to the Django administration console (LMS)

  2. Under Bulk_Email > Bulk email flags I cliked on “Add”

  3. I selected the “Enabled” check box as well as “Require course email auth” checkbox and finally pressed “Save” (as explained in the Open edX documentation: Enabling the Bulk Email Feature — Open edX Release Notes documentation)

  4. Then I went to Bulk_email > Course authorizations and pressed “Add”

  5. I added the id of my course and selected the checkbox “Email enabled” (as explained in How to send mass emails in Open edX? - #2 by gabrieldamours - Educators - Open edX discussions and edx-platform - How to enable BULK EMAIL in the instructor dashboard)

Only after I followed all these steps could I see the “Email” tab in the instruction dashboard of my course. I went to this section and tried to send an email to “myself”. But whenever I press “Send”, the following error appears in the log (and a message “LazyStaticAbsoluteUrl is not JSON serializable” is reported on the platform").

lms_1            | 2021-11-29 20:55:22,863 WARNING 9 [lms.djangoapps.instructor_task.api_helper] [user 5] [ip 89.159.63.160] api_helper.py:89 - No duplicate tasks found: task_type bulk_course_email, task_key eccbc87e4b5ce2fe28308fd9f2a7baf3, and most recent task_id = 3
lms-worker_1     | 2021-11-29 20:55:22,895 INFO 1 [celery.worker.strategy] [user None] [ip None] strategy.py:157 - Received task: lms.djangoapps.instructor_task.tasks.send_bulk_course_email[65f7f463-b958-4486-bfb4-219f0443dac6]  
lms_1            | [pid: 9|app: 0|req: 17860/60128] 172.18.0.12 () {60 vars in 3413 bytes} [Mon Nov 29 20:55:22 2021] POST /courses/.../instructor/api/send_email => generated 67 bytes in 167 msecs (HTTP/1.0 200) 9 headers in 588 bytes (1 switches on core 0)
lms-worker_1     | 2021-11-29 20:55:22,921 INFO 244 [edx.celery.task] [user None] [ip None] runner.py:108 - Task: 65f7f463-b958-4486-bfb4-219f0443dac6, InstructorTask ID: 4, Course: ..., Input: {'email_id': 3, 'to_option': ['myself']}, Starting update (nothing emailed yet)
lms-worker_1     | 2021-11-29 20:55:22,991 INFO 244 [edx.celery.task] [user None] [ip None] tasks.py:194 - Task 65f7f463-b958-4486-bfb4-219f0443dac6: Preparing to queue subtasks for sending emails for course ..., email 3
lms-worker_1     | 2021-11-29 20:55:22,993 INFO 244 [edx.celery.task] [user None] [ip None] subtasks.py:309 - Task 65f7f463-b958-4486-bfb4-219f0443dac6: updating InstructorTask 4 with subtask info for 1 subtasks to process 1 items.
lms-worker_1     | 2021-11-29 20:55:22,998 INFO 244 [edx.celery.task] [user None] [ip None] subtasks.py:332 - Task 65f7f463-b958-4486-bfb4-219f0443dac6: creating 1 subtasks to process 1 items.
lms-worker_1     | 2021-11-29 20:55:23,000 INFO 244 [edx.celery.task] [user None] [ip None] subtasks.py:344 - Queueing BulkEmail Task: 65f7f463-b958-4486-bfb4-219f0443dac6 Subtask: 2bd983ad-a9b6-4db5-aea0-0ec00d08599d at timestamp: 2021-11-29 20:55:23.000729
lms-worker_1     | 2021-11-29 20:55:23,017 WARNING 244 [edx.celery.task] [user None] [ip None] tasks_base.py:96 - Task (65f7f463-b958-4486-bfb4-219f0443dac6) failed
lms-worker_1     | Traceback (most recent call last):
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/serialization.py", line 50, in _reraise_errors
lms-worker_1     |     yield
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/serialization.py", line 221, in dumps
lms-worker_1     |     payload = encoder(data)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/utils/json.py", line 69, in dumps
lms-worker_1     |     return _dumps(s, cls=cls or _default_encoder,
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/__init__.py", line 398, in dumps
lms-worker_1     |     return cls(
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/encoder.py", line 296, in encode
lms-worker_1     |     chunks = self.iterencode(o, _one_shot=True)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/encoder.py", line 378, in iterencode
lms-worker_1     |     return _iterencode(o, 0)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/utils/json.py", line 59, in default
lms-worker_1     |     return super(JSONEncoder, self).default(o)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/encoder.py", line 272, in default
lms-worker_1     |     raise TypeError('Object of type %s is not JSON serializable' %
lms-worker_1     | TypeError: Object of type LazyStaticAbsoluteUrl is not JSON serializable
lms-worker_1     | 
lms-worker_1     | During handling of the above exception, another exception occurred:
lms-worker_1     | 
lms-worker_1     | Traceback (most recent call last):
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/celery/app/trace.py", line 412, in trace_task
lms-worker_1     |     R = retval = fun(*args, **kwargs)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/celery/app/trace.py", line 704, in __protected_call__
lms-worker_1     |     return self.run(*args, **kwargs)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/edx_django_utils/monitoring/internal/code_owner/utils.py", line 179, in new_function
lms-worker_1     |     return wrapped_function(*args, **kwargs)
lms-worker_1     |   File "/openedx/edx-platform/lms/djangoapps/instructor_task/tasks.py", line 164, in send_bulk_course_email
lms-worker_1     |     return run_main_task(entry_id, visit_fcn, action_name)
lms-worker_1     |   File "/openedx/edx-platform/lms/djangoapps/instructor_task/tasks_helper/runner.py", line 120, in run_main_task
lms-worker_1     |     task_progress = task_fcn(entry_id, course_id, task_input, action_name)
lms-worker_1     |   File "/openedx/edx-platform/lms/djangoapps/bulk_email/tasks.py", line 221, in perform_delegate_email_batches
lms-worker_1     |     progress = queue_subtasks_for_query(
lms-worker_1     |   File "/openedx/edx-platform/lms/djangoapps/instructor_task/subtasks.py", line 348, in queue_subtasks_for_query
lms-worker_1     |     new_subtask.apply_async()
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/celery/canvas.py", line 235, in apply_async
lms-worker_1     |     return _apply(args, kwargs, **options)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/celery/app/task.py", line 566, in apply_async
lms-worker_1     |     return app.send_task(
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/celery/app/base.py", line 741, in send_task
lms-worker_1     |     amqp.send_task_message(P, name, message, **options)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/celery/app/amqp.py", line 552, in send_task_message
lms-worker_1     |     ret = producer.publish(
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/messaging.py", line 167, in publish
lms-worker_1     |     body, content_type, content_encoding = self._prepare(
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/messaging.py", line 252, in _prepare
lms-worker_1     |     body) = dumps(body, serializer=serializer)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/serialization.py", line 221, in dumps
lms-worker_1     |     payload = encoder(data)
lms-worker_1     |   File "/opt/pyenv/versions/3.8.6/lib/python3.8/contextlib.py", line 131, in __exit__
lms-worker_1     |     self.gen.throw(type, value, traceback)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/serialization.py", line 54, in _reraise_errors
lms-worker_1     |     reraise(wrapper, wrapper(exc), sys.exc_info()[2])
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/vine/five.py", line 194, in reraise
lms-worker_1     |     raise value.with_traceback(tb)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/serialization.py", line 50, in _reraise_errors
lms-worker_1     |     yield
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/serialization.py", line 221, in dumps
lms-worker_1     |     payload = encoder(data)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/utils/json.py", line 69, in dumps
lms-worker_1     |     return _dumps(s, cls=cls or _default_encoder,
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/__init__.py", line 398, in dumps
lms-worker_1     |     return cls(
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/encoder.py", line 296, in encode
lms-worker_1     |     chunks = self.iterencode(o, _one_shot=True)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/encoder.py", line 378, in iterencode
lms-worker_1     |     return _iterencode(o, 0)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/utils/json.py", line 59, in default
lms-worker_1     |     return super(JSONEncoder, self).default(o)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/encoder.py", line 272, in default
lms-worker_1     |     raise TypeError('Object of type %s is not JSON serializable' %
lms-worker_1     | kombu.exceptions.EncodeError: Object of type LazyStaticAbsoluteUrl is not JSON serializable
lms-worker_1     | 2021-11-29 20:55:23,029 ERROR 244 [celery.app.trace] [user None] [ip None] trace.py:255 - Task lms.djangoapps.instructor_task.tasks.send_bulk_course_email[65f7f463-b958-4486-bfb4-219f0443dac6] raised unexpected: EncodeError(TypeError('Object of type LazyStaticAbsoluteUrl is not JSON serializable'))
lms-worker_1     | Traceback (most recent call last):
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/serialization.py", line 50, in _reraise_errors
lms-worker_1     |     yield
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/serialization.py", line 221, in dumps
lms-worker_1     |     payload = encoder(data)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/utils/json.py", line 69, in dumps
lms-worker_1     |     return _dumps(s, cls=cls or _default_encoder,
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/__init__.py", line 398, in dumps
lms-worker_1     |     return cls(
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/encoder.py", line 296, in encode
lms-worker_1     |     chunks = self.iterencode(o, _one_shot=True)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/encoder.py", line 378, in iterencode
lms-worker_1     |     return _iterencode(o, 0)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/utils/json.py", line 59, in default
lms-worker_1     |     return super(JSONEncoder, self).default(o)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/encoder.py", line 272, in default
lms-worker_1     |     raise TypeError('Object of type %s is not JSON serializable' %
lms-worker_1     | TypeError: Object of type LazyStaticAbsoluteUrl is not JSON serializable
lms-worker_1     | 
lms-worker_1     | During handling of the above exception, another exception occurred:
lms-worker_1     | 
lms-worker_1     | Traceback (most recent call last):
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/celery/app/trace.py", line 412, in trace_task
lms-worker_1     |     R = retval = fun(*args, **kwargs)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/celery/app/trace.py", line 704, in __protected_call__
lms-worker_1     |     return self.run(*args, **kwargs)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/edx_django_utils/monitoring/internal/code_owner/utils.py", line 179, in new_function
lms-worker_1     |     return wrapped_function(*args, **kwargs)
lms-worker_1     |   File "/openedx/edx-platform/lms/djangoapps/instructor_task/tasks.py", line 164, in send_bulk_course_email
lms-worker_1     |     return run_main_task(entry_id, visit_fcn, action_name)
lms-worker_1     |   File "/openedx/edx-platform/lms/djangoapps/instructor_task/tasks_helper/runner.py", line 120, in run_main_task
lms-worker_1     |     task_progress = task_fcn(entry_id, course_id, task_input, action_name)
lms-worker_1     |   File "/openedx/edx-platform/lms/djangoapps/bulk_email/tasks.py", line 221, in perform_delegate_email_batches
lms-worker_1     |     progress = queue_subtasks_for_query(
lms-worker_1     |   File "/openedx/edx-platform/lms/djangoapps/instructor_task/subtasks.py", line 348, in queue_subtasks_for_query
lms-worker_1     |     new_subtask.apply_async()
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/celery/canvas.py", line 235, in apply_async
lms-worker_1     |     return _apply(args, kwargs, **options)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/celery/app/task.py", line 566, in apply_async
lms-worker_1     |     return app.send_task(
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/celery/app/base.py", line 741, in send_task
lms-worker_1     |     amqp.send_task_message(P, name, message, **options)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/celery/app/amqp.py", line 552, in send_task_message
lms-worker_1     |     ret = producer.publish(
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/messaging.py", line 167, in publish
lms-worker_1     |     body, content_type, content_encoding = self._prepare(
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/messaging.py", line 252, in _prepare
lms-worker_1     |     body) = dumps(body, serializer=serializer)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/serialization.py", line 221, in dumps
lms-worker_1     |     payload = encoder(data)
lms-worker_1     |   File "/opt/pyenv/versions/3.8.6/lib/python3.8/contextlib.py", line 131, in __exit__
lms-worker_1     |     self.gen.throw(type, value, traceback)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/serialization.py", line 54, in _reraise_errors
lms-worker_1     |     reraise(wrapper, wrapper(exc), sys.exc_info()[2])
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/vine/five.py", line 194, in reraise
lms-worker_1     |     raise value.with_traceback(tb)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/serialization.py", line 50, in _reraise_errors
lms-worker_1     |     yield
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/serialization.py", line 221, in dumps
lms-worker_1     |     payload = encoder(data)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/utils/json.py", line 69, in dumps
lms-worker_1     |     return _dumps(s, cls=cls or _default_encoder,
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/__init__.py", line 398, in dumps
lms-worker_1     |     return cls(
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/encoder.py", line 296, in encode
lms-worker_1     |     chunks = self.iterencode(o, _one_shot=True)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/encoder.py", line 378, in iterencode
lms-worker_1     |     return _iterencode(o, 0)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/kombu/utils/json.py", line 59, in default
lms-worker_1     |     return super(JSONEncoder, self).default(o)
lms-worker_1     |   File "/openedx/venv/lib/python3.8/site-packages/simplejson/encoder.py", line 272, in default
lms-worker_1     |     raise TypeError('Object of type %s is not JSON serializable' %
lms-worker_1     | kombu.exceptions.EncodeError: Object of type LazyStaticAbsoluteUrl is not JSON serializable

Hi @regis, were my explanations on how I obtained the issue clear/accurate enough ?
I am planning to upgrade from Lilac to Maple soon and will check if the error persists.

Hi all,
I am experiencing the same problem with tutor version 13.0.3 in maple.

Here is my stack trace:

2022-01-11 13:50:10,591 ERROR 12 [celery.app.trace] [user None] [ip None] trace.py:255 - Task lms.djangoapps.instructor_task.tasks.send_bulk_course_email[26b93357-018a-408f-b3f7-b69722447c5b] raised unexpected: EncodeError(TypeError('Object of type LazyStaticAbsoluteUrl is not JSON serializable'))
Traceback (most recent call last):
  File "/openedx/venv/lib/python3.8/site-packages/kombu/serialization.py", line 50, in _reraise_errors
    yield
  File "/openedx/venv/lib/python3.8/site-packages/kombu/serialization.py", line 221, in dumps
    payload = encoder(data)
  File "/openedx/venv/lib/python3.8/site-packages/kombu/utils/json.py", line 69, in dumps
    return _dumps(s, cls=cls or _default_encoder,
  File "/openedx/venv/lib/python3.8/site-packages/simplejson/__init__.py", line 398, in dumps
    return cls(
  File "/openedx/venv/lib/python3.8/site-packages/simplejson/encoder.py", line 296, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/openedx/venv/lib/python3.8/site-packages/simplejson/encoder.py", line 378, in iterencode
    return _iterencode(o, 0)
  File "/openedx/venv/lib/python3.8/site-packages/kombu/utils/json.py", line 59, in default
    return super(JSONEncoder, self).default(o)
  File "/openedx/venv/lib/python3.8/site-packages/simplejson/encoder.py", line 272, in default
    raise TypeError('Object of type %s is not JSON serializable' %
TypeError: Object of type LazyStaticAbsoluteUrl is not JSON serializable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/openedx/venv/lib/python3.8/site-packages/celery/app/trace.py", line 412, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/openedx/venv/lib/python3.8/site-packages/celery/app/trace.py", line 704, in __protected_call__
    return self.run(*args, **kwargs)
  File "/openedx/venv/lib/python3.8/site-packages/edx_django_utils/monitoring/internal/code_owner/utils.py", line 193, in new_function
    return wrapped_function(*args, **kwargs)
  File "/openedx/edx-platform/lms/djangoapps/instructor_task/tasks.py", line 164, in send_bulk_course_email
    return run_main_task(entry_id, visit_fcn, action_name)
  File "/openedx/edx-platform/lms/djangoapps/instructor_task/tasks_helper/runner.py", line 120, in run_main_task
    task_progress = task_fcn(entry_id, course_id, task_input, action_name)
  File "/openedx/edx-platform/lms/djangoapps/bulk_email/tasks.py", line 221, in perform_delegate_email_batches
    progress = queue_subtasks_for_query(
  File "/openedx/edx-platform/lms/djangoapps/instructor_task/subtasks.py", line 347, in queue_subtasks_for_query
    new_subtask.apply_async()
  File "/openedx/venv/lib/python3.8/site-packages/celery/canvas.py", line 235, in apply_async
    return _apply(args, kwargs, **options)
  File "/openedx/venv/lib/python3.8/site-packages/celery/app/task.py", line 566, in apply_async
    return app.send_task(
  File "/openedx/venv/lib/python3.8/site-packages/celery/app/base.py", line 741, in send_task
    amqp.send_task_message(P, name, message, **options)
  File "/openedx/venv/lib/python3.8/site-packages/celery/app/amqp.py", line 552, in send_task_message
    ret = producer.publish(
  File "/openedx/venv/lib/python3.8/site-packages/kombu/messaging.py", line 167, in publish
    body, content_type, content_encoding = self._prepare(
  File "/openedx/venv/lib/python3.8/site-packages/kombu/messaging.py", line 252, in _prepare
    body) = dumps(body, serializer=serializer)
  File "/openedx/venv/lib/python3.8/site-packages/kombu/serialization.py", line 221, in dumps
    payload = encoder(data)
  File "/opt/pyenv/versions/3.8.12/lib/python3.8/contextlib.py", line 131, in __exit__
    self.gen.throw(type, value, traceback)
  File "/openedx/venv/lib/python3.8/site-packages/kombu/serialization.py", line 54, in _reraise_errors
    reraise(wrapper, wrapper(exc), sys.exc_info()[2])
  File "/openedx/venv/lib/python3.8/site-packages/vine/five.py", line 194, in reraise
    raise value.with_traceback(tb)
  File "/openedx/venv/lib/python3.8/site-packages/kombu/serialization.py", line 50, in _reraise_errors
    yield
  File "/openedx/venv/lib/python3.8/site-packages/kombu/serialization.py", line 221, in dumps
    payload = encoder(data)
  File "/openedx/venv/lib/python3.8/site-packages/kombu/utils/json.py", line 69, in dumps
    return _dumps(s, cls=cls or _default_encoder,
  File "/openedx/venv/lib/python3.8/site-packages/simplejson/__init__.py", line 398, in dumps
    return cls(
  File "/openedx/venv/lib/python3.8/site-packages/simplejson/encoder.py", line 296, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/openedx/venv/lib/python3.8/site-packages/simplejson/encoder.py", line 378, in iterencode
    return _iterencode(o, 0)
  File "/openedx/venv/lib/python3.8/site-packages/kombu/utils/json.py", line 59, in default
    return super(JSONEncoder, self).default(o)
  File "/openedx/venv/lib/python3.8/site-packages/simplejson/encoder.py", line 272, in default
    raise TypeError('Object of type %s is not JSON serializable' %
kombu.exceptions.EncodeError: Object of type LazyStaticAbsoluteUrl is not JSON serializable
1 Like

This is what I’ve found:
Kombu uses its own json serializer, and it calls the __json__ method for unknown classes:

So I added the __json__ method in the same way as the to_json in the LazyStaticAbsoluteUrl class:

    def __json__(self):
        return str(self)

Now the error is gone and the logs look better:

2022-01-11 16:22:26,589 INFO 1 [celery.worker.strategy] [user None] [ip None] strategy.py:157 - Received task: lms.djangoapps.instructor_task.tasks.send_bulk_course_email[975f5f3f-c87e-49d4-9db5-b3e5eb8bfa33]  
2022-01-11 16:22:26,648 INFO 12 [edx.celery.task] [user None] [ip None] runner.py:108 - Task: 975f5f3f-c87e-49d4-9db5-b3e5eb8bfa33, InstructorTask ID: 14, Course: course-v1:edX+DemoX+Demo_Course, Input: {'email_id': 14, 'to_option': ['myself']}, Starting update (nothing emailed yet)
2022-01-11 16:22:26,677 INFO 12 [edx.celery.task] [user None] [ip None] tasks.py:194 - Task 975f5f3f-c87e-49d4-9db5-b3e5eb8bfa33: Preparing to queue subtasks for sending emails for course course-v1:edX+DemoX+Demo_Course, email 14
2022-01-11 16:22:26,678 INFO 12 [edx.celery.task] [user None] [ip None] subtasks.py:308 - Task 975f5f3f-c87e-49d4-9db5-b3e5eb8bfa33: updating InstructorTask 14 with subtask info for 1 subtasks to process 1 items.
2022-01-11 16:22:26,693 INFO 12 [edx.celery.task] [user None] [ip None] subtasks.py:331 - Task 975f5f3f-c87e-49d4-9db5-b3e5eb8bfa33: creating 1 subtasks to process 1 items.
2022-01-11 16:22:26,695 INFO 12 [edx.celery.task] [user None] [ip None] subtasks.py:343 - Queueing BulkEmail Task: 975f5f3f-c87e-49d4-9db5-b3e5eb8bfa33 Subtask: 85e6691c-b494-45e3-b41c-a4c7d22c1794 at timestamp: 2022-01-11 16:22:26.695370
2022-01-11 16:22:26,735 INFO 12 [edx.celery.task] [user None] [ip None] runner.py:126 - Task: 975f5f3f-c87e-49d4-9db5-b3e5eb8bfa33, InstructorTask ID: 14, Course: course-v1:edX+DemoX+Demo_Course, Input: {'email_id': 14, 'to_option': ['myself']}, Task type: emailed, Finishing task: {'action_name': 'emailed', 'attempted': 0, 'failed': 0, 'skipped': 0, 'succeeded': 0, 'total': 1, 'duration_ms': 0, 'start_time': 1641918146.6798043}
2022-01-11 16:22:26,739 INFO 12 [celery.app.trace] [user None] [ip None] trace.py:125 - Task lms.djangoapps.instructor_task.tasks.send_bulk_course_email[975f5f3f-c87e-49d4-9db5-b3e5eb8bfa33] succeeded in 0.141009203158319s: {'action_name': 'emailed', 'attempted': 0, 'failed': 0, 'skipped': 0, 'succeeded': 0, 'total': 1, 'duration_ms': 0, 'start_time': 1641918146.6798043}

However, I cannot get the emails sent. They stay in “PROGRESS” “Incomplete”.

Any idea?

Good catch everyone! Luckily, because we recently merged this other PR we can now get rid of that LazyStaticUrl nonsense which is causing us so much trouble. See this PR: Comparing master...regisb/fix-bulk-emails · overhangio/tutor · GitHub