Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KeyError: 'body-count' when opening a page with WagtailFormBlock in streamfields #214

Open
pdeero opened this issue Apr 13, 2023 · 4 comments

Comments

@pdeero
Copy link

pdeero commented Apr 13, 2023

I am encountering a KeyError: 'body-count' error when trying to open a page for editing in Wagtail that includes a WagtailFormBlock in the streamfields.

Steps to reproduce:

Create a page with a WagtailFormBlock in the streamfields
You should not be able to see the body cause it should be buggy cause the WagtailFormBlock

Actual behavior:

Encountering a KeyError: 'body-count' error when attempting to open the page for editing.

Environment:

Django==4.1.1
wagtail==4.2.2
wagtail_localize==1.3.3
django-extensions==3.2.0
psycopg2==2.9.3
loglevel==0.1.2
Wand==0.6.10
django-redis==5.2.0
sentry-sdk==1.10.1
wagtail-honeypot==1.0.0
wagtail-transfer==0.8.5
wagtailstreamforms==3.22.0

Used page class:

class LandingPage(Page):
    template = "home/landing_page.html"
    body = StreamField([
        ('form', WagtailFormBlock())
    ])
    content_panels = Page.content_panels + [
        FieldPanel("body"),
    ]

    parent_page_types = ["hintbox.HomePage"]
    subpage_types = []

    class Meta:
        verbose_name = "Landing Page"

Console error:

Traceback (most recent call last):
  File "/Users/pdeero/Projekte/website/venv/lib/python3.8/site-packages/django/utils/datastructures.py", line 84, in __getitem__
    list_ = super().__getitem__(key)
KeyError: 'body-count'

During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/Users/pdeero/Projekte/website/venv/lib/python3.8/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
  File "/Users/pdeero/Projekte/website/venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/pdeero/Projekte/website/venv/lib/python3.8/site-packages/django/views/decorators/cache.py", line 62, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "/Users/pdeero/Projekte/website/venv/lib/python3.8/site-packages/wagtail/admin/urls/__init__.py", line 175, in wrapper
    return view_func(request, *args, **kwargs)
  File "/Users/pdeero/Projekte/website/venv/lib/python3.8/site-packages/wagtail/admin/auth.py", line 186, in decorated_view
    response = view_func(request, *args, **kwargs)
  File "/Users/pdeero/Projekte/website/venv/lib/python3.8/site-packages/django/views/generic/base.py", line 103, in view
    return self.dispatch(request, *args, **kwargs)
  File "/Users/pdeero/Projekte/website/venv/lib/python3.8/site-packages/wagtail/admin/views/generic/preview.py", line 30, in dispatch
    return super().dispatch(request, *args, **kwargs)
  File "/Users/pdeero/Projekte/website/venv/lib/python3.8/site-packages/django/views/generic/base.py", line 142, in dispatch
    return handler(request, *args, **kwargs)
  File "/Users/pdeero/Projekte/website/venv/lib/python3.8/site-packages/wagtail/admin/views/generic/preview.py", line 73, in post
    form = self.get_form(request.POST)
  File "/Users/pdeero/Projekte/website/venv/lib/python3.8/site-packages/wagtail/admin/views/pages/preview.py", line 98, in get_form
    if form.is_valid():
  File "/Users/pdeero/Projekte/website/venv/lib/python3.8/site-packages/wagtail/admin/forms/pages.py", line 176, in is_valid
    return super().is_valid()
  File "/Users/pdeero/Projekte/website/venv/lib/python3.8/site-packages/modelcluster/forms.py", line 343, in is_valid
    form_is_valid = super().is_valid()
  File "/Users/pdeero/Projekte/website/venv/lib/python3.8/site-packages/django/forms/forms.py", line 205, in is_valid
    return self.is_bound and not self.errors
  File "/Users/pdeero/Projekte/website/venv/lib/python3.8/site-packages/django/forms/forms.py", line 200, in errors
    self.full_clean()
  File "/Users/pdeero/Projekte/website/venv/lib/python3.8/site-packages/django/forms/forms.py", line 437, in full_clean
    self._clean_fields()
  File "/Users/pdeero/Projekte/website/venv/lib/python3.8/site-packages/django/forms/forms.py", line 444, in _clean_fields
    value = bf.initial if field.disabled else bf.data
  File "/Users/pdeero/Projekte/website/venv/lib/python3.8/site-packages/django/forms/boundfield.py", line 127, in data
    return self.form._widget_data_value(self.field.widget, self.html_name)
  File "/Users/pdeero/Projekte/website/venv/lib/python3.8/site-packages/django/forms/forms.py", line 224, in _widget_data_value
    return widget.value_from_datadict(self.data, self.files, html_name)
  File "/Users/pdeero/Projekte/website/venv/lib/python3.8/site-packages/wagtail/blocks/base.py", line 576, in value_from_datadict
    return self.block_def.value_from_datadict(data, files, name)
  File "/Users/pdeero/Projekte/website/venv/lib/python3.8/site-packages/wagtail/blocks/stream_block.py", line 104, in value_from_datadict
    count = int(data["%s-count" % prefix])
  File "/Users/pdeero/Projekte/website/venv/lib/python3.8/site-packages/django/utils/datastructures.py", line 86, in __getitem__
    raise MultiValueDictKeyError(key)
django.utils.datastructures.MultiValueDictKeyError: 'body-count'

Please let me know if there is any further information I can provide to help troubleshoot this issue.

Thanks for help in advance.

@pdeero
Copy link
Author

pdeero commented Apr 19, 2023

Does anybody has an idea to fix this problem?

@umair313
Copy link

having the same issue looking for solution.

@umair313
Copy link

For me re-starting the server fix the solution.

@mrharpo
Copy link

mrharpo commented Dec 20, 2024

We've been getting this error in our project occasionally as well. It seems to happen when the server has been on for more than a day or two, and goes away on restart.

When it happens, the admin edit page loads fine, except our custom StreamField appears to be missing all the content (ExhibitPage.body). All other content appears on the page. The error message happens when an editor tries to save the page they are working on. Changes are not saved. The API is unaffected and continues serving the old data, and on server restart, the content appears back on the page, and editing / publishing can resume as normal.

Model

class ExhibitPage(HeadlessMixin, Page):

Logs

Here is a recent stacktrace, in case someone finds it helpful!

Environment:
Request Method: POST
Request URL: https://admin.ov.wgbh-mla.org/admin/pages/21/edit/
Django Version: 5.1.4
Python Version: 3.13.1
Installed Applications:
['home',
 'authors',
 'exhibits',
 'ov_collections',
 'ov_wag',
 'search',
 'wagtail.contrib.forms',
 'wagtail.contrib.redirects',
 'wagtail.contrib.styleguide',
 'wagtail.embeds',
 'wagtail.sites',
 'wagtail.users',
 'wagtail.snippets',
 'wagtail.documents',
 'wagtail.images',
 'wagtail.search',
 'wagtail.admin',
 'wagtail',
 'wagtail.api.v2',
 'corsheaders',
 'rest_framework',
 'modelcluster',
 'taggit',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'wagtail_headless_preview',
 'wagtail.contrib.search_promotions',
 'wagtail_footnotes',
 'django.contrib.sites',
 'allauth',
 'allauth.account',
 'allauth.socialaccount',
 'allauth.socialaccount.providers.auth0',
 'storages']
Installed Middleware:
['corsheaders.middleware.CorsMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'django.middleware.security.SecurityMiddleware',
 'wagtail.contrib.redirects.middleware.RedirectMiddleware',
 'allauth.account.middleware.AccountMiddleware']
Traceback (most recent call last):
  File "/usr/local/lib/python3.13/site-packages/django/utils/datastructures.py", line 84, in __getitem__
    list_ = super().__getitem__(key)
            ^^^^^^^^^^^^^^^^^^^^^^^^
During handling of the above exception ('body-count'), another exception occurred:
  File "/usr/local/lib/python3.13/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/django/views/decorators/cache.py", line 80, in _view_wrapper
    response = view_func(request, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/wagtail/admin/urls/__init__.py", line 172, in wrapper
    return view_func(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/wagtail/admin/auth.py", line 151, in decorated_view
    response = view_func(request, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/django/views/generic/base.py", line 104, in view
    return self.dispatch(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/wagtail/admin/views/pages/edit.py", line 396, in dispatch
    return super().dispatch(request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/django/views/generic/base.py", line 143, in dispatch
    return handler(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/wagtail/admin/views/pages/edit.py", line 478, in post
    if self.form.is_valid() and not self.locked_for_user:
       ^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/wagtail/admin/forms/pages.py", line 202, in is_valid
    return super().is_valid()
           ^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/modelcluster/forms.py", line 343, in is_valid
    form_is_valid = super().is_valid()
                    ^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/django/forms/forms.py", line 197, in is_valid
    return self.is_bound and not self.errors
                                 ^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/django/forms/forms.py", line 192, in errors
    self.full_clean()
    ^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/django/forms/forms.py", line 325, in full_clean
    self._clean_fields()
    ^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/django/forms/forms.py", line 333, in _clean_fields
    self.cleaned_data[name] = field._clean_bound_field(bf)
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/django/forms/fields.py", line 265, in _clean_bound_field
    value = bf.initial if self.disabled else bf.data
                                             ^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/django/forms/boundfield.py", line 136, in data
    return self.form._widget_data_value(self.field.widget, self.html_name)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/django/forms/forms.py", line 216, in _widget_data_value
    return widget.value_from_datadict(self.data, self.files, html_name)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/wagtail/blocks/base.py", line 640, in value_from_datadict
    return self.block_def.value_from_datadict(data, files, name)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/wagtail/blocks/stream_block.py", line 120, in value_from_datadict
    count = int(data["%s-count" % prefix])
                ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.13/site-packages/django/utils/datastructures.py", line 86, in __getitem__
    raise MultiValueDictKeyError(key)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Exception Type: MultiValueDictKeyError at /admin/pages/21/edit/
Exception Value: 'body-count'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants