Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,26 @@ def _bot_connection_references(client, bot_id: str) -> list[dict[str, Any]]:

refs: list[dict[str, Any]] = []
for change in changes:
item = (
change.get("connectionReference")
if isinstance(change, dict)
else None
)
if not isinstance(item, dict):
# Surface a malformed individual entry instead of silently skipping it
# (PR #304 review): a non-dict change, or a ``connectionReference`` that
# is present but not an object, no longer matches the validated
# contract, so raise and let the owning check degrade to a WARNING. An
# absent or null ``connectionReference`` is tolerated (a non-connection
# change) and skipped.
if not isinstance(change, dict):
raise ValueError(
"Component fetch returned a malformed "
"connectionReferenceChanges entry."
)
if "connectionReference" not in change:
continue
item = change.get("connectionReference")
if item is None:
continue
if not isinstance(item, dict):
raise ValueError(
"Component fetch returned a malformed connectionReference entry."
)
refs.append(
{
"botid": bot_id,
Expand Down
35 changes: 35 additions & 0 deletions tests/flightcheck/checks/test_da_connection_refs.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,41 @@ def test_read_active_malformed_change_set_raises():
reader.read_active_agent_connection_references(runner)


def test_read_active_non_dict_change_entry_raises():
# An individual change that is not an object is surfaced, not skipped.
runner = _FakeRunner(
_FakeClient({"BOT": {"connectionReferenceChanges": ["oops"]}}),
{"agent": {"botId": "BOT"}},
)
with pytest.raises(ValueError):
reader.read_active_agent_connection_references(runner)


def test_read_active_malformed_individual_reference_raises():
# connectionReference present but not an object -> surfaced, not "not found".
payload = {
"connectionReferenceChanges": [
{"changeType": "Insert", "connectionReference": "not-an-object"}
]
}
runner = _FakeRunner(_FakeClient({"BOT": payload}), {"agent": {"botId": "BOT"}})
with pytest.raises(ValueError):
reader.read_active_agent_connection_references(runner)


def test_read_active_change_without_reference_is_tolerated():
# A change carrying no (or null) connectionReference is a non-connection
# change: skipped, not raised.
payload = {
"connectionReferenceChanges": [
{"changeType": "Delete"},
{"changeType": "Insert", "connectionReference": None},
]
}
runner = _FakeRunner(_FakeClient({"BOT": payload}), {"agent": {"botId": "BOT"}})
assert reader.read_active_agent_connection_references(runner) == []


# --------------------------------------------------------------------------
# read_all_agents_connection_references (ENV-004 surface: env-wide, de-duped)
# --------------------------------------------------------------------------
Expand Down
Loading