Unable to create Hue scene entity for

Hue scene setup error on restart caused by bridge_home scenes (/groups/0)

I ran into a Home Assistant Hue integration startup error where several Hue scenes failed to create as HA scene entities.

I'm NOT going to file this as a issue on GitHub (there are more important Hue things to get into HA than this - such as #151883 and #156617...) but it's here for reference if anyone ever hits it.

Environment

  • Home Assistant: 2026.5.2
  • Install type: Home Assistant Container
  • Hue integration: built-in Philips Hue integration
  • Multiple Hue bridges

Error seen in Home Assistant logs

On restart I saw errors like this:

Logger: homeassistant.components.hue.scene
Source: components/hue/scene.py:61
Integration: Philips Hue

Unable to create Hue scene entity for <scene UUID>
Unable to create Hue scene entity for <scene UUID>
Unable to create Hue scene entity for <scene UUID>

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/hue/scene.py", line 61, in async_add_entity
    entity = HueSceneEntity(bridge, api.scenes, resource)
  File "/usr/src/homeassistant/homeassistant/components/hue/scene.py", line 112, in __init__
    self.hue_group = self.controller.get_group(self.resource.id)
  File "/usr/local/lib/python3.14/site-packages/aiohue/v2/controllers/scenes.py", line 100, in get_group
    return next(x for x in self._bridge.groups if x.id == scene.group.rid)
StopIteration

This didn't appear to be causing ANY problems at all other than this annoying error report in the HA logs after every restart.

Root cause found

The failing scenes were valid Hue scenes, but they were not attached to a normal Hue room or zone.

They were attached to the Hue v2 bridge_home resource, which maps to the old Hue v1 /groups/0 whole-bridge group.

In my case the scenes were the standard Hue recipe scenes:

Concentrate
Energize
Nightlight
Read
Relax

The bridge returned them as scenes with:

group.rtype = bridge_home
group.rid   = <bridge_home UUID>
id_v1       = /scenes/<id>

The corresponding bridge_home resource had:

type  = bridge_home
id_v1 = /groups/0

So it looks as if Home Assistant/aiohue tries to resolve the scene group through the normal room/zone group collection, but bridge_home is not found there, causing the StopIteration.

How these got here - who knows, but I suspect they could be from:

  • Setting up a whole home scene on Hub v1 (can't remember doing that but perhaps)
  • Some old Hue labs code
  • Someone setting up a dimmer to apply a scene across the whole house and then reversing it (probably me)
  • As a result of the migration process from Old Hub to Pro this may have been carried into v2
  • Some combination of all the above in a hand waving way of justifying it

Either way I couldn't find a way to remove them in the current Hue app.

Why this was hard to track down

The Home Assistant diagnostics redacted the primary resource IDs, so searching the diagnostics file for the failing scene UUIDs from the log did not work.

The Hue bridge API still had the real scene IDs, so querying the bridge directly was the easiest way to map the log UUIDs back to human-readable scene names.

Example bridge-home output

I have several Hue bridges. Only one bridge had scenes attached to bridge_home.

Example output, with bridge names, IP addresses, and some IDs anonymised:

====================================================================================================
Bridge: Bridge A
Host:   10.x.x.x

bridge_home id:    <bridge_home UUID>
bridge_home id_v1: /groups/0
bridge_home name:  <unnamed>

Children:
  device   <device UUID>  Bridge A
  room     <room UUID>    Room 1
  room     <room UUID>    Room 2
  room     <room UUID>    Room 3
  room     <room UUID>    Room 4
  room     <room UUID>    Room 5

Services:
  grouped_light        <grouped_light UUID>  /groups/0
  grouped_motion       <grouped_motion UUID>
  grouped_light_level  <grouped_light_level UUID>

Scenes attached to bridge_home:
  <scene UUID>  Concentrate  id_v1=/scenes/<id>
  <scene UUID>  Energize     id_v1=/scenes/<id>
  <scene UUID>  Nightlight   id_v1=/scenes/<id>
  <scene UUID>  Read         id_v1=/scenes/<id>
  <scene UUID>  Relax        id_v1=/scenes/<id>

====================================================================================================
Bridge: Bridge B
Host:   10.x.x.x

bridge_home id:    <bridge_home UUID>
bridge_home id_v1: /groups/0
bridge_home name:  <unnamed>

Scenes attached to bridge_home:
  <none>

====================================================================================================
Bridge: Bridge C
Host:   10.x.x.x

bridge_home id:    <bridge_home UUID>
bridge_home id_v1: /groups/0
bridge_home name:  <unnamed>

Scenes attached to bridge_home:
  <none>

Script 1 — map failing scene UUIDs to names

Run this inside the Home Assistant container from /config to just confirm you are matching those UUIDs from the HA error log against this problem. Helps make sure this is the issue and that you are running these scripts in the right place!

Edit BAD_SCENES and put in the scene UUIDs from your HA log.

#!/usr/bin/env python3

import json
import ssl
import urllib.request
from pathlib import Path

BAD_SCENES = {
    "PUT-SCENE-UUID-HERE",
    "PUT-SCENE-UUID-HERE",
}

CONFIG = Path("/config/.storage/core.config_entries")
ctx = ssl._create_unverified_context()

def get_json(host, key, path):
    req = urllib.request.Request(
        f"https://{host}/clip/v2/resource/{path}",
        headers={"hue-application-key": key},
    )
    with urllib.request.urlopen(req, context=ctx, timeout=10) as r:
        payload = json.load(r)

    if payload.get("errors"):
        raise RuntimeError(payload["errors"])

    return payload.get("data", [])

with CONFIG.open() as f:
    entries = json.load(f)["data"]["entries"]

for entry in entries:
    if entry.get("domain") != "hue":
        continue

    data = entry.get("data", {})
    title = entry.get("title") or entry.get("entry_id")
    host = data.get("host")
    key = (
        data.get("api_key")
        or data.get("application_key")
        or data.get("username")
    )

    print()
    print("=" * 80)
    print(f"Entry: {title}")
    print(f"Host:  {host}")

    if not host or not key:
        print("Missing host or Hue application key in this config entry")
        continue

    try:
        scenes = {s["id"]: s for s in get_json(host, key, "scene")}
        rooms = {r["id"]: r for r in get_json(host, key, "room")}
        zones = {z["id"]: z for z in get_json(host, key, "zone")}
        bridge_homes = {h["id"]: h for h in get_json(host, key, "bridge_home")}
    except Exception as e:
        print(f"Could not query bridge: {e}")
        continue

    found_any = False

    for scene_id in BAD_SCENES:
        scene = scenes.get(scene_id)
        if not scene:
            continue

        found_any = True

        group = scene.get("group", {})
        group_id = group.get("rid")
        group_type = group.get("rtype")

        if group_type == "room":
            group_resource = rooms.get(group_id)
        elif group_type == "zone":
            group_resource = zones.get(group_id)
        elif group_type == "bridge_home":
            group_resource = bridge_homes.get(group_id)
        else:
            group_resource = None

        scene_name = scene.get("metadata", {}).get("name", "<unnamed scene>")
        group_name = (
            group_resource.get("metadata", {}).get("name")
            if group_resource
            else "<missing group>"
        )

        print()
        print(f"Scene ID:   {scene_id}")
        print(f"Scene name: {scene_name}")
        print(f"Group:      {group_type} {group_id}")
        print(f"Group name: {group_name}")

    if not found_any:
        print("None of the failing scene IDs are on this bridge")

Script 2 — print bridge_home resources and scenes on all your Hue bridges

This helped confirm that only one bridge had scenes attached to bridge_home for me - but you may have it on more than one - but at least you will be able to see from this output.

#!/usr/bin/env python3

import json
import ssl
import urllib.request
from pathlib import Path

CONFIG = Path("/config/.storage/core.config_entries")
ctx = ssl._create_unverified_context()

def get_json(host, key, resource):
    req = urllib.request.Request(
        f"https://{host}/clip/v2/resource/{resource}",
        headers={"hue-application-key": key},
    )
    with urllib.request.urlopen(req, context=ctx, timeout=10) as r:
        payload = json.load(r)

    if payload.get("errors"):
        raise RuntimeError(payload["errors"])

    return payload.get("data", [])

def name_of(obj):
    return obj.get("metadata", {}).get("name", "<unnamed>")

with CONFIG.open() as f:
    entries = json.load(f)["data"]["entries"]

for entry in entries:
    if entry.get("domain") != "hue":
        continue

    title = entry.get("title") or entry.get("entry_id")
    data = entry.get("data", {})
    host = data.get("host")
    key = data.get("api_key") or data.get("application_key") or data.get("username")

    print()
    print("=" * 100)
    print(f"Bridge: {title}")
    print(f"Host:   {host}")

    if not host or not key:
        print("Missing host or Hue application key")
        continue

    try:
        bridge_homes = get_json(host, key, "bridge_home")
        rooms = {r["id"]: r for r in get_json(host, key, "room")}
        zones = {z["id"]: z for z in get_json(host, key, "zone")}
        devices = {d["id"]: d for d in get_json(host, key, "device")}
        scenes = get_json(host, key, "scene")
        grouped_lights = {g["id"]: g for g in get_json(host, key, "grouped_light")}
    except Exception as e:
        print(f"ERROR querying bridge: {e}")
        continue

    if not bridge_homes:
        print("No bridge_home resource found")
        continue

    for home in bridge_homes:
        home_id = home["id"]

        print()
        print(f"bridge_home id:    {home_id}")
        print(f"bridge_home id_v1: {home.get('id_v1', '<none>')}")
        print(f"bridge_home name:  {name_of(home)}")

        print()
        print("Children:")
        for child in home.get("children", []):
            rid = child.get("rid")
            rtype = child.get("rtype")

            if rtype == "room":
                label = name_of(rooms.get(rid, {}))
            elif rtype == "zone":
                label = name_of(zones.get(rid, {}))
            elif rtype == "device":
                label = name_of(devices.get(rid, {}))
            else:
                label = "<unknown>"

            print(f"  {rtype:8} {rid}  {label}")

        print()
        print("Services:")
        for service in home.get("services", []):
            rid = service.get("rid")
            rtype = service.get("rtype")

            if rtype == "grouped_light":
                svc = grouped_lights.get(rid, {})
                label = svc.get("id_v1", "") or name_of(svc)
            else:
                label = ""

            print(f"  {rtype:20} {rid}  {label}")

        print()
        print("Scenes attached to bridge_home:")
        home_scenes = [
            s for s in scenes
            if s.get("group", {}).get("rid") == home_id
            and s.get("group", {}).get("rtype") == "bridge_home"
        ]

        if not home_scenes:
            print("  <none>")
        else:
            for s in sorted(home_scenes, key=lambda x: name_of(x).lower()):
                print(f"  {s['id']}  {name_of(s)}  id_v1={s.get('id_v1', '<none>')}")

Script 3 — dry-run and optionally delete stranded bridge_home scenes

The fix. save this script in your /config directory and again run it from inside the container - I called it tidy_hue_bridge_home_scenes.py.

It checks whether the target scenes are still referenced by any Hue behavior_instance to make sure there isn't something in the Hue hub that is actually using these scenes (you may be on a Hue hub v1 which I haven't tested against, or have some dimmer switch that is set to apply to the whole home, or some hue labs thing still active).

Edit:
TARGET_BRIDGE - set it for the bridge you want to remove the scenes from
TARGET_SCENES - set up the scenes and UUID's that you want to remove

If you need to do this on more than one bridge - change them for each bridge and rerun the script.

It runs as a dry run by default. It only deletes if --delete is supplied as a command line argument.

#!/usr/bin/env python3

import argparse
import json
import ssl
import urllib.request
from pathlib import Path

TARGET_BRIDGE = "Bridge A"

TARGET_SCENES = {
    "PUT-SCENE-UUID-HERE": "Scene name here",
    "PUT-SCENE-UUID-HERE": "Scene name here",
}

CONFIG = Path("/config/.storage/core.config_entries")
ctx = ssl._create_unverified_context()

parser = argparse.ArgumentParser()
parser.add_argument("--delete", action="store_true", help="actually delete the scenes")
args = parser.parse_args()

def request(host, key, method, resource):
    req = urllib.request.Request(
        f"https://{host}/clip/v2/resource/{resource}",
        headers={"hue-application-key": key},
        method=method,
    )
    with urllib.request.urlopen(req, context=ctx, timeout=10) as r:
        return json.load(r)

def get_data(host, key, resource):
    payload = request(host, key, "GET", resource)
    if payload.get("errors"):
        raise RuntimeError(payload["errors"])
    return payload.get("data", [])

def contains_scene_id(obj, scene_id):
    if isinstance(obj, dict):
        if obj.get("rid") == scene_id and obj.get("rtype") == "scene":
            return True
        return any(contains_scene_id(v, scene_id) for v in obj.values())

    if isinstance(obj, list):
        return any(contains_scene_id(v, scene_id) for v in obj)

    return False

with CONFIG.open() as f:
    entries = json.load(f)["data"]["entries"]

entry = next(
    e for e in entries
    if e.get("domain") == "hue"
    and (e.get("title") or e.get("entry_id")) == TARGET_BRIDGE
)

data = entry["data"]
host = data["host"]
key = data.get("api_key") or data.get("application_key") or data.get("username")

print(f"Bridge: {TARGET_BRIDGE}")
print(f"Host:   {host}")
print()

scenes = {s["id"]: s for s in get_data(host, key, "scene")}
behaviours = get_data(host, key, "behavior_instance")

for scene_id, expected_name in TARGET_SCENES.items():
    scene = scenes.get(scene_id)

    if not scene:
        print(f"{scene_id} {expected_name}: already absent")
        continue

    actual_name = scene.get("metadata", {}).get("name", "<unnamed>")
    group = scene.get("group", {})

    refs = [
        b for b in behaviours
        if contains_scene_id(b, scene_id)
    ]

    print("-" * 80)
    print(f"Scene: {actual_name}")
    print(f"ID:    {scene_id}")
    print(f"Group: {group.get('rtype')} {group.get('rid')}")
    print(f"Refs:  {len(refs)} behavior_instance reference(s)")

    if refs:
        print("NOT deleting because it is still referenced:")
        for b in refs:
            print(f"  {b.get('id')}  {b.get('metadata', {}).get('name', '<unnamed>')}")
        continue

    if args.delete:
        result = request(host, key, "DELETE", f"scene/{scene_id}")
        print("DELETE result:")
        print(json.dumps(result, indent=2))
    else:
        print("Dry run only. Would delete with --delete.")

Run dry first:

python3 tidy_hue_bridge_home_scenes.py

If all target scenes show zero behavior_instance references, add the --delete argument:

python3 tidy_hue_bridge_home_scenes.py --delete

Then run dry again to confirm they have been deleted:

python3 tidy_hue_bridge_home_scenes.py

After deleting the stranded bridge_home scenes, re-running the script should show something like:

<scene UUID> Concentrate: already absent
<scene UUID> Energize: already absent
<scene UUID> Nightlight: already absent
<scene UUID> Read: already absent
<scene UUID> Relax: already absent

The Hue scene setup errors should now disappear on the next Home Assistant restart or Hue integration reload.

Notes / cautions

  • Do not delete scenes unless you have confirmed they are not referenced by Hue behavior_instance.
  • This only checks Hue bridge behaviours, not Home Assistant YAML/UI automations.
  • Consider searching your Home Assistant config for the scene UUIDs before deleting them.
  • I would treat this as a workaround, not necessarily the underlying fix.
  • Home Assistant/aiohue may need to either ignore bridge_home scenes or handle them explicitly instead of raising StopIteration.
1 Like

Thank you for this post! I encountered the same problem, and this completely fixed it. For the record, I have a single Gen 2 bridge (the square one, not the Gen 1 round one, and also not the new Pro bridge). I have no idea how these scenes ended up there, for me they also were standard scenes (although just 4 of them: "night light" was not there). I did play with Labs a few years ago, so that might be it.

Anyway, this method removed those scenes just fine, so thanks again!

1 Like