I’m working on implementing verifiable credentials following the official documentation. I’ve successfully completed most of the setup, but am encountering an issue at the final step.
What I’ve Completed Successfully
Followed the Verifiable Credentials Quickstart guide
Completed the full setup process
Can view course certificates in the Verifiable Credentials app
QR code displays correctly in the modal
Made an entry to the sandbox-registry repo: registry.json#L164-L168
"did:key:z6Mkiq1TLJRWVBt4pdaXv4CCEasnVpoj2qJrnGEJ541L6MJQ": {
"name": "Wikimedia Foundation (Test Issuer)",
"location": "San Francisco, CA, USA",
"url": "https://learnwiki-dev.edly.io/"
}
The Problem
I’m stuck at Step 4 of the Credential Storage documentation.
Issue: When I scan the QR code with the wallet app, it shows “Handling credentials request”, but then nothing happens. The credential is not being stored in the wallet.
Server Error
After checking the credentials service logs, I found the following error occurring when the wallet app attempts to retrieve the credentials:
credentials-1 | 2026-01-29 13:54:11,815 ERROR 8 [django.request] log.py:241 - Internal Server Error: /verifiable_credentials/api/v1/credentials/issue/bdbff49a-442e-45b1-a8a6-356897ba46c9/
credentials-1 | Traceback (most recent call last):
credentials-1 | File "/openedx/venv/lib/python3.11/site-packages/django/core/handlers/exception.py", line 55, in inner
credentials-1 | response = get_response(request)
credentials-1 | ^^^^^^^^^^^^^^^^^^^^^
credentials-1 | File "/openedx/venv/lib/python3.11/site-packages/django/core/handlers/base.py", line 197, in _get_response
credentials-1 | response = wrapped_callback(request, *callback_args, **callback_kwargs)
credentials-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
credentials-1 | File "/openedx/venv/lib/python3.11/site-packages/django/views/decorators/csrf.py", line 56, in wrapper_view
credentials-1 | return view_func(*args, **kwargs)
credentials-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
credentials-1 | File "/openedx/venv/lib/python3.11/site-packages/django/views/generic/base.py", line 104, in view
credentials-1 | return self.dispatch(request, *args, **kwargs)
credentials-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
credentials-1 | File "/openedx/venv/lib/python3.11/site-packages/rest_framework/views.py", line 515, in dispatch
credentials-1 | response = self.handle_exception(exc)
credentials-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
credentials-1 | File "/openedx/venv/lib/python3.11/site-packages/rest_framework/views.py", line 475, in handle_exception
credentials-1 | self.raise_uncaught_exception(exc)
credentials-1 | File "/openedx/venv/lib/python3.11/site-packages/rest_framework/views.py", line 486, in raise_uncaught_exception
credentials-1 | raise exc
credentials-1 | File "/openedx/venv/lib/python3.11/site-packages/rest_framework/views.py", line 503, in dispatch
credentials-1 | self.initial(request, *args, **kwargs)
credentials-1 | File "/openedx/venv/lib/python3.11/site-packages/rest_framework/views.py", line 421, in initial
credentials-1 | self.check_permissions(request)
credentials-1 | File "/openedx/venv/lib/python3.11/site-packages/rest_framework/views.py", line 338, in check_permissions
credentials-1 | if not permission.has_permission(request, self):
credentials-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
credentials-1 | File "/openedx/venv/lib/python3.11/site-packages/rest_framework/permissions.py", line 87, in has_permission
credentials-1 | self.op2.has_permission(request, view)
credentials-1 | File "/openedx/credentials/credentials/apps/verifiable_credentials/permissions.py", line 60, in has_permission
credentials-1 | result = didkit_verify_presentation(presentation_json, proof_options_json)
credentials-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
credentials-1 | File "/openedx/venv/lib/python3.11/site-packages/asgiref/sync.py", line 254, in __call__
credentials-1 | return call_result.result()
credentials-1 | ^^^^^^^^^^^^^^^^^^^^
credentials-1 | File "/opt/pyenv/versions/3.11.9/lib/python3.11/concurrent/futures/_base.py", line 449, in result
credentials-1 | return self.__get_result()
credentials-1 | ^^^^^^^^^^^^^^^^^^^
credentials-1 | File "/opt/pyenv/versions/3.11.9/lib/python3.11/concurrent/futures/_base.py", line 401, in __get_result
credentials-1 | raise self._exception
credentials-1 | File "/openedx/venv/lib/python3.11/site-packages/asgiref/sync.py", line 331, in main_wrap
credentials-1 | result = await self.awaitable(*args, **kwargs)
credentials-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
credentials-1 | File "/openedx/credentials/credentials/apps/verifiable_credentials/issuance/utils.py", line 97, in didkit_verify_presentation
credentials-1 | return await didkit.verify_presentation(
credentials-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
credentials-1 | ValueError: Invalid context at line 1 column 105
The error occurs at the /verifiable_credentials/api/v1/credentials/issue/{uuid}/ endpoint during the permission check phase, specifically when didkit_verify_presentation is called.
Questions
- Has anyone encountered the `ValueError: Invalid context at line 1 column 105` error when setting up verifiable credentials?
- Are there any common configuration issues at this step that I might be missing?
- Could this be related to my sandbox registry entry configuration? Should the context URLs in my registry match specific values?
Environment Details
- Tutor: 20.0.1
- tutor-credentials: 20.0.0
- edx-platform fork: teak
- Python: 3.11.9
Any guidance or suggestions would be greatly appreciated! Thanks in advance for your help.

