# Breaking devstack change

**URL:** <https://discuss.openedx.org/t/breaking-devstack-change/8979>\
**Category:** Development\
**Tags:** devstack\
**Created:** [December 19, 2022, 5:10pm UTC](https://discuss.openedx.org/t/breaking-devstack-change/8979 "2022-12-19T17:10:54Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Agrendalath](https://avatars.discourse-cdn.com/v4/letter/a/c68b51/32.png) [@Agrendalath](https://discuss.openedx.org/u/Agrendalath)\
**Post date:** [December 19, 2022, 5:10pm UTC](https://discuss.openedx.org/t/breaking-devstack-change/8979/1 "2022-12-19T17:10:54Z")

</div>

Hello 👋

Context: this change affects only devstacks running the most recent version of the `master` branch. It does not affect named releases or production deployments.  
More context: this is a part of the [Content Core Platform Simplification project](https://openedx.atlassian.net/wiki/spaces/AC/pages/3091629503/Content+Core+Platform+Simplification).

Currently, various terms refer to XBlocks: “xblocks” (or “blocks”), “descriptors”, “modules”, or “items”. This makes the code a lot less approachable and understandable. Since we are getting rid of a lot of tech debt, we are doing a small refactor of this terminology in the edx-platform to make it consistent. However, it means that we need to introduce some breaking changes. We have just merged [one of the related PRs](https://github.com/openedx/edx-platform/pull/31113) that replaced all occurrences of the term “module” with “block”.

Because of this, you need to reinstall all entry points for XBlocks. To do this, run the following commands in LMS and Studio containers, and restart them.

```bash
make local-requirements &&\
sed -i 's/xmodule.hidden_module.HiddenDescriptor/xmodule.hidden_block.HiddenBlock/' /edx/etc/{lms,studio}.yml &&\
find . -name '*.pyc' -delete

```

Example errors you may encounter without running these commands:

> **ModuleNotFoundError: No module named 'xmodule.capa\_module'**
>
> ```python
> Traceback (most recent call last):
> File "/edx/app/edxapp/edx-platform/openedx/core/djangoapps/user_api/accounts/utils.py", line 174, in retrieve_last_sitewide_block_completed
> item = modulestore().get_item(candidate_block_key, depth=1)
> File "/edx/app/edxapp/edx-platform/xmodule/modulestore/mixed.py", line 81, in inner
> retval = func(field_decorator=strip_key_collection, *args, **kwargs)
> File "/edx/app/edxapp/edx-platform/xmodule/modulestore/mixed.py", line 247, in get_item
> return store.get_item(usage_key, depth, **kwargs)
> File "/edx/app/edxapp/edx-platform/xmodule/modulestore/split_mongo/split_draft.py", line 283, in get_item
> return super().get_item(usage_key, depth=depth, **kwargs)
> File "/edx/app/edxapp/edx-platform/xmodule/modulestore/split_mongo/split.py", line 1183, in get_item
> items = self._load_items(course, [BlockKey.from_usage_key(usage_key)], depth, **kwargs)
> File "/edx/app/edxapp/edx-platform/xmodule/modulestore/split_mongo/split.py", line 780, in _load_items
> return [runtime.load_item(block_key, course_entry, **kwargs) for block_key in block_keys]
> File "/edx/app/edxapp/edx-platform/xmodule/modulestore/split_mongo/split.py", line 780, in <listcomp>
> return [runtime.load_item(block_key, course_entry, **kwargs) for block_key in block_keys]
> File "/edx/app/edxapp/edx-platform/xmodule/modulestore/split_mongo/caching_descriptor_system.py", line 121, in _load_item
> class_ = self.load_block_type(block_data.block_type)
> File "/edx/app/edxapp/edx-platform/xmodule/x_module.py", line 1112, in load_block_type
> return super().load_block_type(block_type)
> File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/xblock/runtime.py", line 621, in load_block_type
> return XBlock.load_class(block_type, self.default_class, self.select)
> File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/xblock/plugin.py", line 115, in load_class
> PLUGIN_CACHE[key] = cls._load_class_entry_point(selected_entry_point)
> File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/xblock/plugin.py", line 70, in _load_class_entry_point
> class_ = entry_point.load()
> File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/pkg_resources/ __init__.py", line 2471, in load
> return self.resolve()
> File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/pkg_resources/ __init__.py", line 2477, in resolve
> module = __import__ (self.module_name, fromlist=[' __name__'], level=0)
> ModuleNotFoundError: No module named 'xmodule.capa_module'
> 
> ```

> **ModuleNotFoundError: No module named 'xmodule.course\_module'**
>
> ```python
> Traceback (most recent call last):
> File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
> response = get_response(request)
> File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response
> response = wrapped_callback(request, *callback_args, **callback_kwargs)
> File "/usr/lib/python3.8/contextlib.py", line 75, in inner
> return func(*args, **kwds)
> File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
> return view_func(*args, **kwargs)
> File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/django/views/generic/base.py", line 70, in view
> return self.dispatch(request, *args, **kwargs)
> File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/rest_framework/views.py", line 509, in dispatch
> response = self.handle_exception(exc)
> File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/rest_framework/views.py", line 469, in handle_exception
> self.raise_uncaught_exception(exc)
> File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
> raise exc
> File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/rest_framework/views.py", line 506, in dispatch
> response = handler(request, *args, **kwargs)
> File "/edx/app/edxapp/edx-platform/lms/djangoapps/course_home_api/course_metadata/views.py", line 125, in get
> 'tabs': get_course_tab_list(request.user, course),
> File "/edx/app/edxapp/edx-platform/lms/djangoapps/courseware/tabs.py", line 330, in get_course_tab_list
> for tab in xmodule_tab_list:
> File "/edx/app/edxapp/edx-platform/xmodule/tabs.py", line 470, in iterate_displayable
> if tab.is_enabled(course, user=user) and (include_hidden or not (user and tab.is_hidden)):
> File "/edx/app/edxapp/edx-platform/lms/djangoapps/course_wiki/tab.py", line 43, in is_enabled
> if course.allow_public_wiki_access:
> File "/edx/app/edxapp/edx-platform/openedx/core/djangoapps/content/course_overviews/models.py", line 835, in allow_public_wiki_access
> return self._original_course.allow_public_wiki_access
> File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/django/utils/functional.py", line 48, in __get__
> res = instance. __dict__ [self.name] = self.func(instance)
> File "/edx/app/edxapp/edx-platform/openedx/core/djangoapps/content/course_overviews/models.py", line 828, in _original_course
> return modulestore().get_course(self.id)
> File "/edx/app/edxapp/edx-platform/xmodule/modulestore/mixed.py", line 81, in inner
> retval = func(field_decorator=strip_key_collection, *args, **kwargs)
> File "/edx/app/edxapp/edx-platform/xmodule/modulestore/mixed.py", line 403, in get_course
> return store.get_course(course_key, depth=depth, **kwargs)
> File "/usr/lib/python3.8/contextlib.py", line 75, in inner
> return func(*args, **kwds)
> File "/edx/app/edxapp/edx-platform/xmodule/modulestore/split_mongo/split_draft.py", line 61, in get_course
> return super().get_course(course_id, depth=depth, **kwargs)
> File "/edx/app/edxapp/edx-platform/xmodule/modulestore/split_mongo/split.py", line 1106, in get_course
> return self._get_structure(course_id, depth, **kwargs)
> File "/edx/app/edxapp/edx-platform/xmodule/modulestore/split_mongo/split.py", line 1096, in _get_structure
> result = self._load_items(structure_entry, [root], depth, **kwargs)
> File "/edx/app/edxapp/edx-platform/xmodule/modulestore/split_mongo/split.py", line 780, in _load_items
> return [runtime.load_item(block_key, course_entry, **kwargs) for block_key in block_keys]
> File "/edx/app/edxapp/edx-platform/xmodule/modulestore/split_mongo/split.py", line 780, in <listcomp>
> return [runtime.load_item(block_key, course_entry, **kwargs) for block_key in block_keys]
> File "/edx/app/edxapp/edx-platform/xmodule/modulestore/split_mongo/caching_descriptor_system.py", line 121, in _load_item
> class_ = self.load_block_type(block_data.block_type)
> File "/edx/app/edxapp/edx-platform/xmodule/x_module.py", line 1112, in load_block_type
> return super().load_block_type(block_type)
> File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/xblock/runtime.py", line 621, in load_block_type
> return XBlock.load_class(block_type, self.default_class, self.select)
> File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/xblock/plugin.py", line 115, in load_class
> PLUGIN_CACHE[key] = cls._load_class_entry_point(selected_entry_point)
> File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/xblock/plugin.py", line 70, in _load_class_entry_point
> class_ = entry_point.load()
> File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/pkg_resources/ __init__.py", line 2471, in load
> return self.resolve()
> File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/site-packages/pkg_resources/ __init__.py", line 2477, in resolve
> module = __import__ (self.module_name, fromlist=[' __name__'], level=0)
> ModuleNotFoundError: No module named 'xmodule.course_module'
> 
> ```

> **ModuleNotFoundError: No module named 'xmodule.hidden\_module'**
>
> ```python
> Traceback (most recent call last):
> File "/edx/app/edxapp/edx-platform/xmodule/modulestore/split_mongo/split.py", line 660, in __init__
> class_ = getattr(import_module(module_path), class_name)
> File "/edx/app/edxapp/venvs/edxapp/lib/python3.8/importlib/ __init__.py", line 127, in import_module
> return _bootstrap._gcd_import(name[level:], package, level)
> File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
> File "<frozen importlib._bootstrap>", line 991, in _find_and_load
> File "<frozen importlib._bootstrap>", line 973, in _find_and_load_unlocked
> ModuleNotFoundError: No module named 'xmodule.hidden_module'
> 
> ```

---

<div class="post-metadata">

**Author:** ![feanil](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.openedx.org/feanil/32/37_2.png) [@feanil](https://discuss.openedx.org/u/feanil)\
**Post date:** [December 20, 2022, 4:35pm UTC](https://discuss.openedx.org/t/breaking-devstack-change/8979/2 "2022-12-20T16:35:04Z")

</div>

Is this also something that we’ll want to include in the Palm release notes since it will affect end-users of Named releases at that point?

---

<div class="post-metadata">

**Author:** ![Agrendalath](https://avatars.discourse-cdn.com/v4/letter/a/c68b51/32.png) [@Agrendalath](https://discuss.openedx.org/u/Agrendalath)\
**Post date:** [December 20, 2022, 4:59pm UTC](https://discuss.openedx.org/t/breaking-devstack-change/8979/3 "2022-12-20T16:59:21Z")

</div>

I don’t think it’s necessary.

1. If somebody upgrades the devstack from Olive to Palm, they will need to install dependencies anyway. Most requirements-related recipes in the Makefile trigger `make local-requirements`.
2. The changes in the `/edx/etc/{lms,studio}.yml` will be included in Docker images once we merge [this PR](https://github.com/openedx/configuration/pull/6833) tomorrow. Recreating a container will replace these files.
