After changing Rack to use "too small" RackType, not able to change RackType again, remove it, or make other edits to Rack #10622

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

Originally created by @ZPrimed on GitHub (Jan 7, 2025).

Originally assigned to: @bctiemann on GitHub.

Deployment Type

Self-hosted

Triage priority

N/A

NetBox Version

v4.1.11

Python Version

3.10

Steps to Reproduce

[steps edited after initial issue creation, but should be correct as of 2025-01-14]

  1. Create a Rack of any number of U (let's use 42 as it's the default), name it "FooRack"
  2. Create a RackType that is smaller than the Rack you initially created - say 16U, name it "TestRT-16U"
  3. [edit: missing from original report] Add a Device to FooRack in a U / position that is "beyond the bounds" of TestRT-16U; e.g. put the Device at U17, or U20, or U42
  4. Create another RackType that is the same number of U as the original Rack - 42U, name it "TestRT-42U"
  5. Edit FooRack, and set the RackType to be TestRT-16U, and Save [this will complete successfully, but probably shouldn't, as TestRT-16U has fewer rack units than FooRack originally did!]
  6. Now, edit FooRack again, and either try to set the RackType to "TestRT-42U", or hit the X next to the RackType in order to try to clear it entirely, and click Save. This will throw an error. In fact, even unrelated changes (like editing the Comments) will throw the same error.

Note: if you FIRST change the Rack to a RackType that has sufficient U for the Rack, this works correctly and will allow you to remove the RackType or change it again on a subsequent save. You only get the error if you choose the wrong-size RackType and save it during step 4.

Expected Behavior

  1. I would prefer that the UI prevent me from self-harm, by warning or erroring that the RackType I was trying to switch my Rack to has fewer U than the existing Rack object I was changing, but this is just a wish/hope
  2. Regardless of 1, the UI should allow me to change the RackType or remove it entirely from a Rack, without throwing errors

Observed Behavior

I receive an error message and am not able to save the changes made to the Rack object:

<class 'ValueError'>

'RackForm' has no field named 'u_height'.

Python version: 3.10.12
NetBox version: 4.1.11
Plugins: 
  netbox_topology_views: 4.1.0

I can reproduce this on the Public Demo instance, same error message other than the differing version numbers & plugins:

<class 'ValueError'>

'RackForm' has no field named 'u_height'.

Python version: 3.10.14
NetBox version: 4.2.0
Plugins: 
  netbox_demo: 0.5.0
Originally created by @ZPrimed on GitHub (Jan 7, 2025). Originally assigned to: @bctiemann on GitHub. ### Deployment Type Self-hosted ### Triage priority N/A ### NetBox Version v4.1.11 ### Python Version 3.10 ### Steps to Reproduce [steps edited after initial issue creation, but should be correct as of 2025-01-14] 1. Create a Rack of any number of U (let's use 42 as it's the default), name it "FooRack" 2. Create a RackType that is **smaller** than the Rack you initially created - say 16U, name it "TestRT-16U" 3. [edit: missing from original report] Add a Device to FooRack in a U / position that is "beyond the bounds" of TestRT-16U; e.g. put the Device at U17, or U20, or U42 4. Create another RackType that is the same number of U as the original Rack - 42U, name it "TestRT-42U" 5. Edit FooRack, and set the RackType to be TestRT-16U, and Save [this will complete successfully, but probably shouldn't, as TestRT-16U has fewer rack units than FooRack originally did!] 6. Now, edit FooRack again, and either try to set the RackType to "TestRT-42U", or hit the X next to the RackType in order to try to clear it entirely, and click Save. This will throw an error. In fact, even unrelated changes (like editing the Comments) will throw the same error. Note: if you FIRST change the Rack to a RackType that has *sufficient* U for the Rack, this works **correctly** and will allow you to remove the RackType or change it again on a subsequent save. You only get the error if you choose the wrong-size RackType and save it during step 4. ### Expected Behavior 1. I would *prefer* that the UI prevent me from self-harm, by warning or erroring that the RackType I was trying to switch my Rack to has fewer U than the existing Rack object I was changing, but this is just a wish/hope 2. Regardless of 1, the UI should allow me to change the RackType or remove it entirely from a Rack, without throwing errors ### Observed Behavior I receive an error message and am not able to save the changes made to the Rack object: ``` <class 'ValueError'> 'RackForm' has no field named 'u_height'. Python version: 3.10.12 NetBox version: 4.1.11 Plugins: netbox_topology_views: 4.1.0 ``` I can reproduce this on the Public Demo instance, same error message other than the differing version numbers & plugins: ``` <class 'ValueError'> 'RackForm' has no field named 'u_height'. Python version: 3.10.14 NetBox version: 4.2.0 Plugins: netbox_demo: 0.5.0 ```
adam added the type: bugstatus: acceptedseverity: medium labels 2025-12-29 21:33:49 +01:00
adam closed this issue 2025-12-29 21:33:49 +01:00
Author
Owner

@bctiemann commented on GitHub (Jan 14, 2025):

@ZPrimed I've been trying to reproduce this under NetBox v4.2 without success. I've been creating 42U racks with no RackType, setting them to TestRT-16U (at which point they assume the height of the RackType, e.g. 16U), and then setting them to TestRT-42U or clearing the RackType entirely. All operations complete successfully (and clearing the RackType leaves the Rack with the height last inherited from the RackType it had).

Are you able to try this in NetBox v4.2? Or does the Rack need to have Devices assigned to it before this breaks?

@bctiemann commented on GitHub (Jan 14, 2025): @ZPrimed I've been trying to reproduce this under NetBox v4.2 without success. I've been creating 42U racks with no RackType, setting them to TestRT-16U (at which point they assume the height of the RackType, e.g. 16U), and then setting them to TestRT-42U or clearing the RackType entirely. All operations complete successfully (and clearing the RackType leaves the Rack with the height last inherited from the RackType it had). Are you able to try this in NetBox v4.2? Or does the Rack need to have Devices assigned to it before this breaks?
Author
Owner

@ZPrimed commented on GitHub (Jan 14, 2025):

@bctiemann I apologize, I did leave out the crucial portion that the rack needs to have at least one device added to it. I was testing against the demo instance and just grabbed some existing demo rack (which already had one or more devices in it) which is why I didn't think to include that in my steps. 🤦 Sorry!

I'm unsure if the actual position of the racked device matters (i.e. does it need to be racked in a U that doesn't exist after selecting the too-small RackType), but I can try a bit more testing later today and will update here.

@ZPrimed commented on GitHub (Jan 14, 2025): @bctiemann I apologize, I did leave out the **crucial** portion that the rack needs to have at least one device added to it. I was testing against the demo instance and just grabbed some existing demo rack (which already had one or more devices in it) which is why I didn't think to include that in my steps. 🤦 Sorry! I'm unsure if the actual position of the racked device matters (i.e. does it need to be racked in a U that doesn't exist after selecting the too-small RackType), but I can try a bit more testing later today and will update here.
Author
Owner

@bctiemann commented on GitHub (Jan 14, 2025):

Verified that the described crash does happen as long as the racked devices are at elevations above what the smaller rack can support, i.e. U30 on a 16U rack.

Also note that the SVG rendering call to /api/dcim/racks/43/elevation/ fails when the smaller rack is selected:

Internal Server Error: /api/dcim/racks/43/elevation/
Traceback (most recent call last):
...
  File "/Users/btman/Development/netbox-community/netbox/netbox/dcim/api/views.py", line 210, in elevation
    drawing = rack.get_elevation_svg(
              ^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/btman/Development/netbox-community/netbox/netbox/dcim/models/racks.py", line 588, in get_elevation_svg
    return elevation.render(face)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/btman/Development/netbox-community/netbox/netbox/dcim/svg/racks.py", line 342, in render
    self.draw_face(face)
  File "/Users/btman/Development/netbox-community/netbox/netbox/dcim/svg/racks.py", line 305, in draw_face
    for unit in self.rack.get_rack_units(face=face, expand_devices=False):
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/btman/Development/netbox-community/netbox/netbox/dcim/models/racks.py", line 494, in get_rack_units
    elevation[device.position]['device'] = device
    ~~~~~~~~~^^^^^^^^^^^^^^^^^
KeyError: Decimal('30.0')
@bctiemann commented on GitHub (Jan 14, 2025): Verified that the described crash does happen as long as the racked devices are at elevations above what the smaller rack can support, i.e. U30 on a 16U rack. Also note that the SVG rendering call to `/api/dcim/racks/43/elevation/` fails when the smaller rack is selected: ``` Internal Server Error: /api/dcim/racks/43/elevation/ Traceback (most recent call last): ... File "/Users/btman/Development/netbox-community/netbox/netbox/dcim/api/views.py", line 210, in elevation drawing = rack.get_elevation_svg( ^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/btman/Development/netbox-community/netbox/netbox/dcim/models/racks.py", line 588, in get_elevation_svg return elevation.render(face) ^^^^^^^^^^^^^^^^^^^^^^ File "/Users/btman/Development/netbox-community/netbox/netbox/dcim/svg/racks.py", line 342, in render self.draw_face(face) File "/Users/btman/Development/netbox-community/netbox/netbox/dcim/svg/racks.py", line 305, in draw_face for unit in self.rack.get_rack_units(face=face, expand_devices=False): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/btman/Development/netbox-community/netbox/netbox/dcim/models/racks.py", line 494, in get_rack_units elevation[device.position]['device'] = device ~~~~~~~~~^^^^^^^^^^^^^^^^^ KeyError: Decimal('30.0') ```
Author
Owner

@ZPrimed commented on GitHub (Jan 14, 2025):

@bctiemann Should I update the repro steps in my initial post to clarify the need for the original rack to have a device in a position that won't exist in the smaller rack, or is that superfluous at this point?

I appreciate the work that everyone puts in on this project and I apologize for creating friction with an incomplete report... If I had the coding skill to assist further I would!

@ZPrimed commented on GitHub (Jan 14, 2025): @bctiemann Should I update the repro steps in my initial post to clarify the need for the original rack to have a device in a position that won't exist in the smaller rack, or is that superfluous at this point? I appreciate the work that everyone puts in on this project and I apologize for creating friction with an incomplete report... If I had the coding skill to assist further I would!
Author
Owner

@bctiemann commented on GitHub (Jan 14, 2025):

@ZPrimed Probably a good idea to add in the repro steps to the initial post to save having to collate it all from the comment thread.

I think the fix here would be to ensure the validation of the Rack (in the model clean method) properly prevents you from setting it to an incompatible RackType, which it currently isn't doing right (it's comparing to the Rack.u_height even when a RackType.u_height has been assigned and should override it); but it also needs to handle ValidationErrors properly which takes a bit more work because of the way RackForm is set up.

@bctiemann commented on GitHub (Jan 14, 2025): @ZPrimed Probably a good idea to add in the repro steps to the initial post to save having to collate it all from the comment thread. I think the fix here would be to ensure the validation of the Rack (in the model `clean` method) properly prevents you from setting it to an incompatible RackType, which it currently isn't doing right (it's comparing to the `Rack.u_height` even when a `RackType.u_height` has been assigned and should override it); but it also needs to handle ValidationErrors properly which takes a bit more work because of the way `RackForm` is set up.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#10622