Misordered changelog entries after deleting a module with components #11785

Closed
opened 2025-12-29 21:49:52 +01:00 by adam · 2 comments
Owner

Originally created by @jeremystretch on GitHub (Oct 28, 2025).

Originally assigned to: @jeremystretch on GitHub.

NetBox Edition

NetBox Community

NetBox Version

v4.4.4

Python Version

3.12

Steps to Reproduce

  1. Create a device with a module bay
  2. Create a module type with an interface
  3. Create a module of that type in the device
  4. Delete the module
  5. Inspect the changelog

Expected Behavior

The changelog entries should be ordered as follows (beginning from step 3 above):

  1. Create the module
  2. Create an interface on the module
  3. Delete the interface
  4. Delete the module

Observed Behavior

The changelog entries appear as:

  1. Create the module
  2. Create an interface on the module
  3. Delete the module
  4. Update the interface (appears to be a no-op?)
  5. Delete the interface

Although the result of the deletion is as expected (both the module and its interface have been removed), the changelog does not accurately reflect the order of operations: In reality, any components of the module are and must be deleted from the database prior to the deletion of the module itself to satisfy foreign key constraints.

It should be noted that similar patterns likely exist elsewhere in the application, where a cascading deletion of dependent objects is not accurately recorded in the changelog. The resolution of this bug should include an audit for all such instances.

Originally created by @jeremystretch on GitHub (Oct 28, 2025). Originally assigned to: @jeremystretch on GitHub. ### NetBox Edition NetBox Community ### NetBox Version v4.4.4 ### Python Version 3.12 ### Steps to Reproduce 1. Create a device with a module bay 2. Create a module type with an interface 3. Create a module of that type in the device 4. Delete the module 5. Inspect the changelog ### Expected Behavior The changelog entries should be ordered as follows (beginning from step 3 above): 1. Create the module 2. Create an interface on the module 3. Delete the interface 4. Delete the module ### Observed Behavior The changelog entries appear as: 1. Create the module 2. Create an interface on the module 3. Delete the module 4. Update the interface (appears to be a no-op?) 5. Delete the interface Although the result of the deletion is as expected (both the module and its interface have been removed), the changelog does not accurately reflect the order of operations: In reality, any components of the module are and must be deleted from the database prior to the deletion of the module itself to satisfy foreign key constraints. It should be noted that similar patterns likely exist elsewhere in the application, where a cascading deletion of dependent objects is not accurately recorded in the changelog. The resolution of this bug should include an audit for all such instances.
adam added the type: bugstatus: acceptednetboxseverity: low labels 2025-12-29 21:49:52 +01:00
adam closed this issue 2025-12-29 21:49:52 +01:00
Author
Owner

@jeremystretch commented on GitHub (Oct 28, 2025):

So far, I've traced this down to Django's deletion collector. For some reason, after sorting collected dependencies, it opts to delete the interfaces after deleting the parent module. Curiously, this is not the case with regular device components: An interface assigned to a device directly will be automatically deleted before its parent device. I suspect this related to the module ForeignKey field being nullable whereas the device ForeignKey is not, but still need to explore further.

@jeremystretch commented on GitHub (Oct 28, 2025): So far, I've traced this down to Django's deletion collector. For some reason, after sorting collected dependencies, it opts to delete the interfaces _after_ deleting the parent module. Curiously, this is not the case with regular device components: An interface assigned to a device directly will be automatically deleted before its parent device. I suspect this related to the `module` ForeignKey field being nullable whereas the `device` ForeignKey is not, but still need to explore further.
Author
Owner

@jeremystretch commented on GitHub (Oct 28, 2025):

I've had some luck overriding CASCADE to force null=False on the field, which fixes the ordering: The interface now gets deleted before the module. However, the collector is still trying to push an update to the interface after the pre_delete signal fires, and I'm not sure why.

@jeremystretch commented on GitHub (Oct 28, 2025): I've had some luck overriding `CASCADE` to force `null=False` on the field, which fixes the ordering: The interface now gets deleted before the module. However, the collector is still trying to push an update to the interface after the `pre_delete` signal fires, and I'm not sure why.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#11785