Skip to content

process_event_rules() broke all events when condition evaluation contains None values. #19633

Open
@ravenrs

Description

@ravenrs

Deployment Type

Self-hosted

NetBox Version

v4.2.2

Python Version

3.12

Steps to Reproduce

  1. Install Netbox 4.2.2 with python 3.12 using documentation.
    here is my system config:
    netbox.json
  2. Create site in web interface (all next action I will do in web interface). Here is needed data:

{
"id": 2,
"url": "http://127.0.0.1:8000/api/dcim/sites/2/",
"display_url": "http://127.0.0.1:8000/dcim/sites/2/",
"display": "test_issue",
"name": "test_issue",
"slug": "test_issue",
"status": {
"value": "active",
"label": "Active"
},
"region": null,
"group": null,
"tenant": null,
"facility": "",
"time_zone": null,
"description": "",
"physical_address": "",
"shipping_address": "",
"latitude": null,
"longitude": null,
"comments": "",
"asns": [],
"tags": [],
"custom_fields": {},
"created": "2025-06-04T08:13:03.378951Z",
"last_updated": "2025-06-04T08:13:03.378995Z",
"circuit_count": 0,
"device_count": 0,
"prefix_count": 0,
"rack_count": 0,
"virtualmachine_count": 0,
"vlan_count": 0
}

  1. Create webhook:

{
"id": 3,
"url": "http://127.0.0.1:8000/api/extras/webhooks/3/",
"display_url": "http://127.0.0.1:8000/extras/webhooks/3/",
"display": "test_issue_wb",
"name": "test_issue_wb",
"description": "",
"payload_url": "http://localhost:9000",
"http_method": "POST",
"http_content_type": "application/json",
"additional_headers": "",
"body_template": "",
"secret": "",
"ssl_verification": true,
"ca_file_path": null,
"custom_fields": {},
"tags": [],
"created": "2025-06-04T08:16:29.243488Z",
"last_updated": "2025-06-04T08:16:29.243519Z"
}

  1. Create event:

{
"id": 4,
"url": "http://127.0.0.1:8000/api/extras/event-rules/4/",
"display_url": "http://127.0.0.1:8000/extras/event-rules/4/",
"display": "test_issue_event_without_condition.",
"object_types": [
"dcim.site"
],
"name": "test_issue_event_without_condition.",
"enabled": true,
"event_types": [
"object_updated"
],
"conditions": null,
"action_type": {
"value": "webhook",
"label": "Webhook"
},
"action_object_type": "extras.webhook",
"action_object_id": 3,
"action_object": {
"id": 3,
"url": "http://127.0.0.1:8000/api/extras/webhooks/3/",
"display": "test_issue_wb",
"name": "test_issue_wb",
"description": ""
},
"description": "",
"custom_fields": {},
"tags": [],
"created": "2025-06-04T08:17:07.624292Z",
"last_updated": "2025-06-04T08:17:25.888092Z"
}

  1. Go to terminal, go to the netbox directory, activate virtual env, run manage.py command for webhook_receiver.

password@Air cd ~Documents/netbox-4.2.2/netbox
password@Air ~/Documents/netbox-4.2.2 source venv/bin/activate
((venv) ) password@Airr ~/Documents/netbox-4.2.2  python netbox/manage.py webhook_receiver
Listening on port http://localhost:9000. Stop with CONTROL-C.

  1. Edit created site, add comment - “test”
  2. Check web hook receiver and make sure that you receive changes

Wed, 04 Jun 2025 08:20:59 GMT 127.0.0.1 "POST / HTTP/1.1" 200 -
Host: localhost:9000
Accept-Encoding: identity
User-Agent: python-urllib3/2.4.0
Content-Type: application/json
Content-Length: 1498

{
"event": "updated",
"timestamp": "2025-06-04T08:20:59.727826+00:00",
"model": "site",
"username": "password",
"request_id": "b2f82525-6118-4427-9a40-659801d432ff",
"data": {
"id": 2,
"url": "/api/dcim/sites/2/",
"display_url": "/dcim/sites/2/",
"display": "test_issue",
"name": "test_issue",
"slug": "test_issue",
"status": {
"value": "active",
"label": "Active"
},
"region": null,
"group": null,
"tenant": null,
"facility": "",
"time_zone": null,
"description": "",
"physical_address": "",
"shipping_address": "",
"latitude": null,
"longitude": null,
"comments": "test",
"asns": [],
"tags": [],
"custom_fields": {},
"created": "2025-06-04T08:13:03.378951Z",
"last_updated": "2025-06-04T08:20:59.675324Z"
},
"snapshots": {
"prechange": {
"created": "2025-06-04T08:13:03.378Z",
"description": "",
"comments": "",
"name": "test_issue",
"slug": "test_issue",
"status": "active",
"region": null,
"group": null,
"tenant": null,
"facility": "",
"time_zone": null,
"physical_address": "",
"shipping_address": "",
"latitude": null,
"longitude": null,
"asns": [],
"custom_fields": {},
"tags": []
},
"postchange": {
"created": "2025-06-04T08:13:03.378Z",
"last_updated": "2025-06-04T08:20:59.675Z",
"description": "",
"comments": "test",
"name": "test_issue",
"slug": "test_issue",
"status": "active",
"region": null,
"group": null,
"tenant": null,
"facility": "",
"time_zone": null,
"physical_address": "",
"shipping_address": "",
"latitude": null,
"longitude": null,
"asns": [],
"custom_fields": {},
"tags": []
}
}
}
Completed request #1

  1. Create new event with condition

{
"id": 5,
"url": "http://127.0.0.1:8000/api/extras/event-rules/5/",
"display_url": "http://127.0.0.1:8000/extras/event-rules/5/",
"display": "test_event_with_condition.",
"object_types": [
"dcim.site"
],
"name": "test_event_with_condition.",
"enabled": true,
"event_types": [
"object_updated"
],
"conditions": {
"op": "contains",
"attr": "data.tenant.name",
"value": "test_value",
"negate": true
},
"action_type": {
"value": "webhook",
"label": "Webhook"
},
"action_object_type": "extras.webhook",
"action_object_id": 3,
"action_object": {
"id": 3,
"url": "http://127.0.0.1:8000/api/extras/webhooks/3/",
"display": "test_issue_wb",
"name": "test_issue_wb",
"description": ""
},
"description": "",
"custom_fields": {},
"tags": [],
"created": "2025-06-04T08:27:43.737571Z",
"last_updated": "2025-06-04T08:30:54.429381Z"
}

  1. Edit created site, delete comment - “test”. Here is change log entry from change log:

"count": 65,
"next": "http://127.0.0.1:8000/api/core/object-changes/?limit=50&offset=50",
"previous": null,
"results": [
{
"id": 65,
"url": "http://127.0.0.1:8000/api/core/object-changes/65/",
"display_url": "http://127.0.0.1:8000/core/changelog/65/",
"display": "DCIM | site test_issue updated by password",
"time": "2025-06-04T08:20:59.686892Z",
"user": {
"id": 1,
"url": "http://127.0.0.1:8000/api/users/users/1/",
"display": "password",
"username": "password"
},
"user_name": "password",
"request_id": "b2f82525-6118-4427-9a40-659801d432ff",
"action": {
"value": "update",
"label": "Updated"
},
"changed_object_type": "dcim.site",
"changed_object_id": 2,
"changed_object": {
"id": 2,
"url": "http://127.0.0.1:8000/api/dcim/sites/2/",
"display": "test_issue",
"name": "test_issue",
"slug": "test_issue",
"description": ""
},
"prechange_data": {
"asns": [],
"name": "test_issue",
"slug": "test_issue",
"tags": [],
"group": null,
"region": null,
"status": "active",
"tenant": null,
"comments": "",
"facility": "",
"latitude": null,
"longitude": null,
"time_zone": null,
"description": "",
"custom_fields": {},
"physical_address": "",
"shipping_address": ""
},
"postchange_data": {
"asns": [],
"name": "test_issue",
"slug": "test_issue",
"tags": [],
"group": null,
"region": null,
"status": "active",
"tenant": null,
"comments": "test",
"facility": "",
"latitude": null,
"longitude": null,
"time_zone": null,
"description": "",
"custom_fields": {},
"physical_address": "",
"shipping_address": ""
}
},

  1. Check web hook receiver and make sure that you didn’t receive any changes for events: test_event_with_condition and test_issue_event_without_condition.

Image
Here we see that there is no any request received only one that we have already received.

I've added try except to code just to show the place of exception:

Image

Here is exeption.

Traceback (most recent call last):
File "/Users/password/Documents/netbox-4.2.2/netbox/extras/events.py", line 91, in process_event_rules
if not event_rule.eval_conditions(data):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/password/Documents/netbox-4.2.2/netbox/extras/models/models.py", line 143, in eval_conditions
return ConditionSet(self.conditions).eval(data)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/password/Documents/netbox-4.2.2/netbox/extras/conditions.py", line 161, in eval
return func(d.eval(data) for d in self.conditions)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/password/Documents/netbox-4.2.2/netbox/extras/conditions.py", line 161, in
return func(d.eval(data) for d in self.conditions)
^^^^^^^^^^^^
File "/Users/password/Documents/netbox-4.2.2/netbox/extras/conditions.py", line 82, in eval
result = self.eval_func(value)
^^^^^^^^^^^^^^^^^^^^^
File "/Users/password/Documents/netbox-4.2.2/netbox/extras/conditions.py", line 116, in eval_contains
return self.value in value
^^^^^^^^^^^^^^^^^^^
TypeError: argument of type 'NoneType' is not iterable

Expected Behavior

Event won't added to queue, don't brake all events in cycle or it can be validate somehow while creating event with such mistakes.

Observed Behavior

All events include an event with a condition containing an error, which runs in a loop after this problematic event with the same obj_type, and actions are not added to the queue as expected.

Metadata

Metadata

Assignees

No one assigned

    Labels

    severity: lowDoes not significantly disrupt application functionality, or a workaround is availablestatus: needs ownerThis issue is tentatively accepted pending a volunteer committed to its implementationtype: bugA confirmed report of unexpected behavior in the application

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions