From 6587ee417d72b66f8f42b7f2db30c6bcc31751bc Mon Sep 17 00:00:00 2001 From: Sola Babatunde Date: Mon, 25 May 2026 12:02:21 +0100 Subject: [PATCH 1/2] IHS-75: Fix cardinality many error message --- infrahub_sdk/node/relationship.py | 12 ++++++++++-- tests/unit/sdk/test_node.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/infrahub_sdk/node/relationship.py b/infrahub_sdk/node/relationship.py index 7457a73a..ae09edfe 100644 --- a/infrahub_sdk/node/relationship.py +++ b/infrahub_sdk/node/relationship.py @@ -163,7 +163,11 @@ def __init__( RelatedNode(name=name, client=self.client, branch=self.branch, schema=schema, data=item) ) else: - raise ValueError(f"Unexpected format for {name} found a {type(data)}, {data}") + raise ValueError( + f"Relationship '{name}' expects a list of nodes (cardinality many), " + f"but received a single {type(data).__name__}. " + f"Wrap the value in a list, e.g. {name}=[value]." + ) def __getitem__(self, item: int) -> RelatedNode: return self.peers[item] # type: ignore[return-value] @@ -296,7 +300,11 @@ def __init__( RelatedNodeSync(name=name, client=self.client, branch=self.branch, schema=schema, data=item) ) else: - raise ValueError(f"Unexpected format for {name} found a {type(data)}, {data}") + raise ValueError( + f"Relationship '{name}' expects a list of nodes (cardinality many), " + f"but received a single {type(data).__name__}. " + f"Wrap the value in a list, e.g. {name}=[value]." + ) def __getitem__(self, item: int) -> RelatedNodeSync: return self.peers[item] # type: ignore[return-value] diff --git a/tests/unit/sdk/test_node.py b/tests/unit/sdk/test_node.py index ec69fa81..18c4753a 100644 --- a/tests/unit/sdk/test_node.py +++ b/tests/unit/sdk/test_node.py @@ -312,6 +312,36 @@ async def test_init_node_data_graphql( assert node.primary_tag.typename == "BuiltinTag" +@pytest.mark.parametrize("client_type", client_types) +async def test_cardinality_many_requires_list( + client: InfrahubClient, location_schema: NodeSchemaAPI, client_type: str +) -> None: + data = { + "name": {"value": "JFK1"}, + "tags": {"id": "pppppppp"}, + } + with pytest.raises(ValueError, match=r"expects a list of nodes"): + if client_type == "standard": + InfrahubNode(client=client, schema=location_schema, data=data) + else: + InfrahubNodeSync(client=client, schema=location_schema, data=data) + + +@pytest.mark.parametrize("client_type", client_types) +async def test_cardinality_many_accepts_list( + client: InfrahubClient, location_schema: NodeSchemaAPI, client_type: str +) -> None: + data = { + "name": {"value": "JFK1"}, + "tags": [{"id": "aaaaaa"}, {"id": "bbbb"}], + } + if client_type == "standard": + node = InfrahubNode(client=client, schema=location_schema, data=data) + else: + node = InfrahubNodeSync(client=client, schema=location_schema, data=data) + assert len(node.tags.peers) == 2 + + @pytest.mark.parametrize("client_type", client_types) async def test_query_data_no_filters_property( clients: BothClients, location_schema: NodeSchemaAPI, client_type: str From 329c647eea8a17b5bcb505070d86cb5c4b7c2033 Mon Sep 17 00:00:00 2001 From: Sola Babatunde Date: Mon, 25 May 2026 12:23:23 +0100 Subject: [PATCH 2/2] update news fragment --- changelog/174.fixed.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog/174.fixed.md diff --git a/changelog/174.fixed.md b/changelog/174.fixed.md new file mode 100644 index 00000000..a64cfa8a --- /dev/null +++ b/changelog/174.fixed.md @@ -0,0 +1 @@ +Improve error message when a single node is passed to a cardinality-many relationship.