/api/status/ returns JSON serialization error with django-health-check installed #723

Closed
opened 2026-04-05 17:18:39 +02:00 by MrUnknownDE · 0 comments
Owner

Originally created by @dantte-lp on 12/16/2025

NetBox Edition

NetBox Community

NetBox Version

v4.4.8

Python Version

3.12

Steps to Reproduce

  1. Install NetBox 4.4.8
  2. Install django-health-check package (version 3.20.0)
  3. Add health_check to Django's INSTALLED_APPS
  4. Access /api/status/ endpoint

Expected Behavior

The /api/status/ endpoint should return a valid JSON response containing version information for all installed apps.

Observed Behavior

The endpoint returns:

TypeError: Object of type type is not JSON serializable

Root Cause Analysis:

The django-health-check package uses setuptools-scm for versioning. In their health_check/__init__.py:

from health_check import _version
VERSION = _version.VERSION_TUPLE

Due to how setuptools-scm generates _version.py, VERSION_TUPLE is defined as:

VERSION_TUPLE: Tuple[int, int, int] = object  # type placeholder at runtime

At runtime, VERSION_TUPLE is actually <class 'object'> rather than an actual tuple like (3, 20, 0).

The get_installed_apps() function in netbox/utilities/apps.py retrieves this VERSION attribute and attempts to include it in the response dictionary. Since <class 'object'> is not JSON-serializable, the API call fails.

Suggested Fix:

Add a check in get_installed_apps() to skip VERSION values that are neither tuples nor strings:

if version := getattr(app, 'VERSION', getattr(app, '__version__', None)):
    if type(version) is tuple:
        version = '.'.join(str(n) for n in version)
    elif not isinstance(version, str):
        # Skip non-serializable version types
        continue
    installed_apps[app_config.name] = version

This defensive approach ensures that any third-party package with a non-standard VERSION attribute won't break the /api/status/ endpoint.

I have a fix ready and would be happy to submit a PR if this issue is assigned to me.

*Originally created by @dantte-lp on 12/16/2025* ### NetBox Edition NetBox Community ### NetBox Version v4.4.8 ### Python Version 3.12 ### Steps to Reproduce 1. Install NetBox 4.4.8 2. Install `django-health-check` package (version 3.20.0) 3. Add `health_check` to Django's `INSTALLED_APPS` 4. Access `/api/status/` endpoint ### Expected Behavior The `/api/status/` endpoint should return a valid JSON response containing version information for all installed apps. ### Observed Behavior The endpoint returns: ``` TypeError: Object of type type is not JSON serializable ``` **Root Cause Analysis:** The `django-health-check` package uses `setuptools-scm` for versioning. In their `health_check/__init__.py`: ```python from health_check import _version VERSION = _version.VERSION_TUPLE ``` Due to how `setuptools-scm` generates `_version.py`, `VERSION_TUPLE` is defined as: ```python VERSION_TUPLE: Tuple[int, int, int] = object # type placeholder at runtime ``` At runtime, `VERSION_TUPLE` is actually `<class 'object'>` rather than an actual tuple like `(3, 20, 0)`. The `get_installed_apps()` function in `netbox/utilities/apps.py` retrieves this `VERSION` attribute and attempts to include it in the response dictionary. Since `<class 'object'>` is not JSON-serializable, the API call fails. **Suggested Fix:** Add a check in `get_installed_apps()` to skip VERSION values that are neither tuples nor strings: ```python if version := getattr(app, 'VERSION', getattr(app, '__version__', None)): if type(version) is tuple: version = '.'.join(str(n) for n in version) elif not isinstance(version, str): # Skip non-serializable version types continue installed_apps[app_config.name] = version ``` This defensive approach ensures that any third-party package with a non-standard VERSION attribute won't break the `/api/status/` endpoint. I have a fix ready and would be happy to submit a PR if this issue is assigned to me.
MrUnknownDE added the netboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetboxnetbox labels 2026-04-05 17:18:57 +02:00
Sign in to join this conversation.
No Label netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox netbox
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github/netbox#723