Skip to content

Fix inverse helper device linking (breaks in HA 2026.8) #1227

Merged
frenck merged 15 commits into
frenck:mainfrom
andrew-codechimp:fix-inverse-helper
May 28, 2026
Merged

Fix inverse helper device linking (breaks in HA 2026.8) #1227
frenck merged 15 commits into
frenck:mainfrom
andrew-codechimp:fix-inverse-helper

Conversation

@andrew-codechimp
Copy link
Copy Markdown
Contributor

Description

The Inverse helper uses the old method of attaching itself to the device, which will stop working in 2026.8.

Due to the helper method for migration being introduced in 2025.8 I've bumped the HACS min version to that.

Motivation and Context

There is an updated pattern to correctly do this
https://developers.home-assistant.io/blog/2025/07/18/updated-pattern-for-helpers-linking-to-devices/

I've done quite a few of these on other helper, just tidying up any I see as there's no deprecation warning.

How has this been tested?

Using HA 2026.3.4 I created an inverse switch helper against an existing switch.
I replaced the files for the inverse sub integration and checked the inverse helper config entry was migrated to 1.2.
Checked the inverse switch was still attached to the device.
Created a new inverse helper to check that future switches also worked correctly.

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Other

Checklist

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 30, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds config-entry migration and a helper to resolve a source entity's device_id, updates inverse entities to accept hass and store resolved device entries, adjusts setup call sites, adds config flow versioning, and bumps Home Assistant compatibility in hacs.json.

Changes

Cohort / File(s) Summary
Migration & helpers
custom_components/spook/integrations/spook_inverse/__init__.py
Added async_get_source_entity_device_id(hass, entity_id), async_migrate_entry(hass, config_entry) (handles version/minor_version migration, resolves source entity → device_id, calls removal helper, updates options and sets MIGRATION_MINOR_VERSION).
Entity constructor & device handling
custom_components/spook/integrations/spook_inverse/entity.py
Constructors now accept hass: HomeAssistant; removed device_info property and instead resolve/store device_entry on the instance during init.
Setup call sites
custom_components/spook/integrations/spook_inverse/binary_sensor.py, custom_components/spook/integrations/spook_inverse/switch.py
async_setup_entry now instantiates entities with (hass, config_entry) instead of only (config_entry).
Config flow versioning
custom_components/spook/integrations/spook_inverse/config_flow.py
Added VERSION = 1 and MINOR_VERSION = 2 to SpookInverseConfigFlowHandler.
HACS constraint
hacs.json
Bumped Home Assistant compatibility from 2025.2.0 to 2025.8.0.

Sequence Diagram

sequenceDiagram
    participant ConfigEntry
    participant Migrator as async_migrate_entry
    participant EntityReg as EntityRegistry
    participant DeviceReg as DeviceRegistry
    participant SourceDevice

    ConfigEntry->>Migrator: run migration (version==1, minor < MIGRATION_MINOR_VERSION)
    Migrator->>EntityReg: lookup entity (options[CONF_ENTITY_ID]) -> get device_id
    EntityReg-->>Migrator: device_id or None
    alt device_id found
        Migrator->>DeviceReg: async_remove_helper_config_entry_from_source_device(entry_id, device_id)
        DeviceReg->>SourceDevice: remove helper config entry
        SourceDevice-->>DeviceReg: ack
        DeviceReg-->>Migrator: removal complete
    end
    Migrator->>ConfigEntry: update options, set minor_version = MIGRATION_MINOR_VERSION
    ConfigEntry-->>Migrator: persisted
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

bugfix

Poem

🐰 I hopped through registries to trace a thread,
Found the device where source entities led,
A minor bump, options kept tight,
Helpers moved to the proper site,
Hoppity migration — tidy and light!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: fixing the inverse helper device linking to work with Home Assistant 2026.8+ by updating to the new pattern introduced in 2025.8.
Description check ✅ Passed The description is directly related to the changeset, explaining why the update is needed, referencing the Home Assistant developers blog post about the updated pattern, and documenting the testing performed.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
custom_components/spook/integrations/spook_inverse/__init__.py (1)

77-91: Consider addressing static analysis hints (optional).

Ruff flagged two style issues:

  1. PLR2004: Magic value 2 in the comparison
  2. SIM102: Nested if statements could be combined

These are minor style improvements and don't affect correctness. The migration logic itself is correct.

Optional refactor addressing both hints
+MIGRATION_MINOR_VERSION = 2
+
+
 async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
     """Migrate old entry."""
-
-    if config_entry.version == 1:
-        options = {**config_entry.options}
-        if config_entry.minor_version < 2:
-            # Remove the spook_inverse config entry from the source device
-            if source_device_id := async_get_source_entity_device_id(
+    if config_entry.version == 1 and config_entry.minor_version < MIGRATION_MINOR_VERSION:
+        options = {**config_entry.options}
+        # Remove the spook_inverse config entry from the source device
+        if source_device_id := async_get_source_entity_device_id(
+            hass, options[CONF_ENTITY_ID]
+        ):
+            async_remove_helper_config_entry_from_source_device(
+                hass,
+                helper_config_entry_id=config_entry.entry_id,
+                source_device_id=source_device_id,
+            )
+        hass.config_entries.async_update_entry(
+            config_entry, options=options, minor_version=MIGRATION_MINOR_VERSION
+        )
+    elif config_entry.version == 1:
+        # Already at latest minor version, just ensure options are preserved
+        hass.config_entries.async_update_entry(
+            config_entry, options={**config_entry.options}, minor_version=MIGRATION_MINOR_VERSION
+        )
+
+    return True

Note: The simpler fix is just addressing the docstring blank line (pipeline failure). The constant extraction and if-statement flattening are truly optional given the localized nature of this migration code.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@custom_components/spook/integrations/spook_inverse/__init__.py` around lines
77 - 91, Extract the magic number 2 into a named constant (e.g.,
TARGET_MINOR_VERSION = 2) and simplify the nested conditionals by combining
checks on config_entry.version and config_entry.minor_version into a single if
(use config_entry.version and config_entry.minor_version together), then perform
the existing migration steps: get options from config_entry.options, call
async_get_source_entity_device_id(hass, options[CONF_ENTITY_ID]) and, if it
returns a source_device_id, call
async_remove_helper_config_entry_from_source_device(...) with
helper_config_entry_id=config_entry.entry_id, and finally call
hass.config_entries.async_update_entry(config_entry, options=options,
minor_version=TARGET_MINOR_VERSION); reference symbols: config_entry.version,
config_entry.minor_version, options, async_get_source_entity_device_id,
async_remove_helper_config_entry_from_source_device, and
hass.config_entries.async_update_entry.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@custom_components/spook/integrations/spook_inverse/__init__.py`:
- Around line 74-76: The function async_migrate_entry currently has a blank line
immediately after its docstring which triggers D202; remove the empty line so
the docstring is directly followed by the next statement or return in
async_migrate_entry to satisfy the Ruff docstring rule; ensure no other blank
lines exist between the triple-quoted docstring and following code in that
function.

---

Nitpick comments:
In `@custom_components/spook/integrations/spook_inverse/__init__.py`:
- Around line 77-91: Extract the magic number 2 into a named constant (e.g.,
TARGET_MINOR_VERSION = 2) and simplify the nested conditionals by combining
checks on config_entry.version and config_entry.minor_version into a single if
(use config_entry.version and config_entry.minor_version together), then perform
the existing migration steps: get options from config_entry.options, call
async_get_source_entity_device_id(hass, options[CONF_ENTITY_ID]) and, if it
returns a source_device_id, call
async_remove_helper_config_entry_from_source_device(...) with
helper_config_entry_id=config_entry.entry_id, and finally call
hass.config_entries.async_update_entry(config_entry, options=options,
minor_version=TARGET_MINOR_VERSION); reference symbols: config_entry.version,
config_entry.minor_version, options, async_get_source_entity_device_id,
async_remove_helper_config_entry_from_source_device, and
hass.config_entries.async_update_entry.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: c5b07e00-e6ae-41c3-96f7-b74f0875fd72

📥 Commits

Reviewing files that changed from the base of the PR and between d8d1d3e and 965e45b.

📒 Files selected for processing (6)
  • custom_components/spook/integrations/spook_inverse/__init__.py
  • custom_components/spook/integrations/spook_inverse/binary_sensor.py
  • custom_components/spook/integrations/spook_inverse/config_flow.py
  • custom_components/spook/integrations/spook_inverse/entity.py
  • custom_components/spook/integrations/spook_inverse/switch.py
  • hacs.json

Comment thread custom_components/spook/integrations/spook_inverse/__init__.py Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@custom_components/spook/integrations/spook_inverse/__init__.py`:
- Around line 74-95: Run the Ruff formatter to fix failing style checks: format
the file containing the async_migrate_entry function (the migration logic using
async_get_source_entity_device_id and
async_remove_helper_config_entry_from_source_device) with ruff format, then
re-run ruff --check; this will normalize spacing/line breaks and ensure the
async_migrate_entry block and its calls (hass.config_entries.async_update_entry,
async_remove_helper_config_entry_from_source_device) meet the project's
formatter rules so CI passes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: b62955b3-b7f9-41a9-949f-e1a5800332bc

📥 Commits

Reviewing files that changed from the base of the PR and between 965e45b and 350966a.

📒 Files selected for processing (1)
  • custom_components/spook/integrations/spook_inverse/__init__.py

Comment thread custom_components/spook/integrations/spook_inverse/__init__.py
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
custom_components/spook/integrations/spook_inverse/__init__.py (1)

77-96: Consider avoiding redundant entry updates when already at target version.

The SonarCloud warning about missing async features is a false positive—Home Assistant's framework expects async_migrate_entry to be async even when the implementation doesn't await.

However, async_update_entry is called unconditionally for version 1 entries, even when minor_version already equals MIGRATION_MINOR_VERSION. This causes unnecessary config entry writes on each load for already-migrated entries.

♻️ Proposed fix
 async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
     """Migrate old entry."""
-    if config_entry.version == 1:
+    if config_entry.version == 1 and config_entry.minor_version < MIGRATION_MINOR_VERSION:
         options = {**config_entry.options}
-        if config_entry.minor_version < MIGRATION_MINOR_VERSION and (
-            source_device_id := async_get_source_entity_device_id(
-                hass, options[CONF_ENTITY_ID]
-            )
-        ):
+        if source_device_id := async_get_source_entity_device_id(
+            hass, options[CONF_ENTITY_ID]
+        ):
             # Remove the spook_inverse config entry from the source device
             async_remove_helper_config_entry_from_source_device(
                 hass,
                 helper_config_entry_id=config_entry.entry_id,
                 source_device_id=source_device_id,
             )
         hass.config_entries.async_update_entry(
             config_entry, options=options, minor_version=MIGRATION_MINOR_VERSION
         )

     return True
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@custom_components/spook/integrations/spook_inverse/__init__.py` around lines
77 - 96, The migration currently always calls
hass.config_entries.async_update_entry for entries with config_entry.version ==
1, causing redundant writes even when config_entry.minor_version is already
MIGRATION_MINOR_VERSION; modify async_migrate_entry so you only call
hass.config_entries.async_update_entry when config_entry.minor_version <
MIGRATION_MINOR_VERSION (i.e., after you may have removed the helper via
async_remove_helper_config_entry_from_source_device using
async_get_source_entity_device_id), otherwise return True without updating the
entry.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@custom_components/spook/integrations/spook_inverse/__init__.py`:
- Around line 77-96: The migration currently always calls
hass.config_entries.async_update_entry for entries with config_entry.version ==
1, causing redundant writes even when config_entry.minor_version is already
MIGRATION_MINOR_VERSION; modify async_migrate_entry so you only call
hass.config_entries.async_update_entry when config_entry.minor_version <
MIGRATION_MINOR_VERSION (i.e., after you may have removed the helper via
async_remove_helper_config_entry_from_source_device using
async_get_source_entity_device_id), otherwise return True without updating the
entry.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 1f1903a2-2335-4552-a72f-8eec9b9cba08

📥 Commits

Reviewing files that changed from the base of the PR and between 350966a and 67dc162.

📒 Files selected for processing (1)
  • custom_components/spook/integrations/spook_inverse/__init__.py

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
custom_components/spook/integrations/spook_inverse/__init__.py (1)

77-97: Consider removing unnecessary options copy.

The options dictionary on line 83 is copied but never modified before being passed to async_update_entry. You can pass config_entry.options directly.

♻️ Proposed simplification
 async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool:
     """Migrate old entry."""
     if (
         config_entry.version == 1
         and config_entry.minor_version < MIGRATION_MINOR_VERSION
     ):
-        options = {**config_entry.options}
         if source_device_id := async_get_source_entity_device_id(
-            hass, options[CONF_ENTITY_ID]
+            hass, config_entry.options[CONF_ENTITY_ID]
         ):
             # Remove the spook_inverse config entry from the source device
             async_remove_helper_config_entry_from_source_device(
                 hass,
                 helper_config_entry_id=config_entry.entry_id,
                 source_device_id=source_device_id,
             )
         hass.config_entries.async_update_entry(
-            config_entry, options=options, minor_version=MIGRATION_MINOR_VERSION
+            config_entry, minor_version=MIGRATION_MINOR_VERSION
         )

     return True

Note on SonarCloud warning: The async keyword is required here because Home Assistant's integration framework expects async_migrate_entry to have an async signature, even when the implementation doesn't need to await anything. This is a false positive from SonarCloud.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@custom_components/spook/integrations/spook_inverse/__init__.py` around lines
77 - 97, The options dict is copied into a new variable but never modified;
inside async_migrate_entry replace the unnecessary shallow copy (options =
{**config_entry.options}) by using config_entry.options directly when calling
hass.config_entries.async_update_entry, keeping the same conditional logic
around async_get_source_entity_device_id and
async_remove_helper_config_entry_from_source_device and preserving the
minor_version update via hass.config_entries.async_update_entry(config_entry,
options=config_entry.options, minor_version=...).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@custom_components/spook/integrations/spook_inverse/__init__.py`:
- Around line 77-97: The options dict is copied into a new variable but never
modified; inside async_migrate_entry replace the unnecessary shallow copy
(options = {**config_entry.options}) by using config_entry.options directly when
calling hass.config_entries.async_update_entry, keeping the same conditional
logic around async_get_source_entity_device_id and
async_remove_helper_config_entry_from_source_device and preserving the
minor_version update via hass.config_entries.async_update_entry(config_entry,
options=config_entry.options, minor_version=...).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 663274e2-91ab-4084-8ee6-6634de7cff7c

📥 Commits

Reviewing files that changed from the base of the PR and between 67dc162 and 81c7923.

📒 Files selected for processing (1)
  • custom_components/spook/integrations/spook_inverse/__init__.py

@sonarqubecloud
Copy link
Copy Markdown

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
custom_components/spook/integrations/spook_inverse/__init__.py (1)

79-80: Use MIGRATION_MINOR_VERSION instead of hardcoded 2.

Line 80 hardcodes the threshold, which can drift from Line 17 over time. Prefer comparing against the exported constant directly.

Proposed refactor
-    if (
-        config_entry.version == 1 and config_entry.minor_version < 2  # noqa: PLR2004
-    ):
+    if (
+        config_entry.version == 1
+        and config_entry.minor_version < MIGRATION_MINOR_VERSION
+    ):
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@custom_components/spook/integrations/spook_inverse/__init__.py` around lines
79 - 80, Replace the hardcoded threshold in the migration check with the
exported constant: change the conditional that currently reads "if
(config_entry.version == 1 and config_entry.minor_version < 2)" to compare
against MIGRATION_MINOR_VERSION instead (use config_entry.minor_version <
MIGRATION_MINOR_VERSION); update the import/namespace reference if needed so
MIGRATION_MINOR_VERSION (the constant defined earlier) is used within the block
that handles config_entry migration.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@custom_components/spook/integrations/spook_inverse/__init__.py`:
- Around line 83-85: Guard against missing CONF_ENTITY_ID and unresolved entity
IDs by fetching the entity id via options.get(CONF_ENTITY_ID) into a local
variable (e.g., entity_id = options.get(CONF_ENTITY_ID)) before calling
async_get_source_entity_device_id, and only call
async_get_source_entity_device_id(hass, entity_id) if entity_id is truthy; if
async_get_source_entity_device_id returns None, log a warning (or debug)
indicating the entity could not be resolved and skip device cleanup instead of
silently doing nothing. Ensure you reference options, CONF_ENTITY_ID, and
async_get_source_entity_device_id in the change so the behavior is explicit and
safe during migration.

---

Nitpick comments:
In `@custom_components/spook/integrations/spook_inverse/__init__.py`:
- Around line 79-80: Replace the hardcoded threshold in the migration check with
the exported constant: change the conditional that currently reads "if
(config_entry.version == 1 and config_entry.minor_version < 2)" to compare
against MIGRATION_MINOR_VERSION instead (use config_entry.minor_version <
MIGRATION_MINOR_VERSION); update the import/namespace reference if needed so
MIGRATION_MINOR_VERSION (the constant defined earlier) is used within the block
that handles config_entry migration.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 0c505abe-e3e8-4645-8344-4a76467b0615

📥 Commits

Reviewing files that changed from the base of the PR and between 81c7923 and f8db285.

📒 Files selected for processing (1)
  • custom_components/spook/integrations/spook_inverse/__init__.py

Comment thread custom_components/spook/integrations/spook_inverse/__init__.py Outdated
@frenckatron frenckatron added the bugfix Inconsistencies or issues which will cause a problem for users or implementors. label May 28, 2026
@frenckatron frenckatron force-pushed the fix-inverse-helper branch from f8db285 to 1b99383 Compare May 28, 2026 07:29
@frenckatron
Copy link
Copy Markdown
Collaborator

I rebased this onto current main, kept the newer Home Assistant minimum from hacs.json, addressed the migration safety review comment, and added tests for the migration/device cleanup behavior.

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented May 28, 2026

Codecov Report

❌ Patch coverage is 85.18519% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 60.29%. Comparing base (91512cc) to head (392d063).

Files with missing lines Patch % Lines
...nents/spook/integrations/spook_inverse/__init__.py 84.21% 1 Missing and 2 partials ⚠️
.../spook/integrations/spook_inverse/binary_sensor.py 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1227      +/-   ##
==========================================
+ Coverage   56.96%   60.29%   +3.33%     
==========================================
  Files         119      119              
  Lines        3016     3035      +19     
  Branches      386      390       +4     
==========================================
+ Hits         1718     1830     +112     
+ Misses       1262     1166      -96     
- Partials       36       39       +3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread tests/integrations/spook_inverse/test_init.py Outdated
Comment thread tests/integrations/spook_inverse/test_init.py Outdated
Comment thread tests/integrations/spook_inverse/test_init.py Outdated
@sonarqubecloud
Copy link
Copy Markdown

Copy link
Copy Markdown
Owner

@frenck frenck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @andrew-codechimp 👍

../Frenck

                       

Blogging my personal ramblings at frenck.dev

@frenck frenck merged commit 0f5fba8 into frenck:main May 28, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Inconsistencies or issues which will cause a problem for users or implementors.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants