TypeError thrown at some PDU devices #6921

Closed
opened 2025-12-29 19:46:42 +01:00 by adam · 11 comments
Owner

Originally created by @baschdello on GitHub (Sep 1, 2022).

Originally assigned to: @arthanson on GitHub.

NetBox version

v3.3.0

Python version

3.9

Steps to Reproduce

  1. upgraded netbox to v3.3.0
  2. click at an affected pdu (device)

Expected Behavior

I expect that the pdu device is displayed.

Observed Behavior

An error page with "TypeError" is thrown. Not every pdu is affected although of same device type.

If deleting the cable of an affected pdu to the power feed, the pdu device is opened correctly. If I create the cable again, the type error page is present instead of the device page.
With option "DEBUG = True" in configuration.py the type error page displays some helpful information (attached at bottom). I think there is something wrong at the power utilization graph because of type mismatch.

Template error:
In template /opt/netbox/netbox/templates/dcim/device.html, error at line 252
   unsupported operand type(s) for /: 'str' and 'int'
   242 :                                         {% else %}
   243 :                                             <td class="text-muted">&mdash;</td>
   244 :                                             <td class="text-muted">&mdash;</td>
   245 :                                         {% endif %}
   246 :                                     </tr>
   247 :                                     {% for leg in utilization.legs %}
   248 :                                         <tr>
   249 :                                             <td style="padding-left: 20px">Leg {{ leg.name }}</td>
   250 :                                             <td>{{ leg.outlet_count }}</td>
   251 :                                             <td>{{ leg.allocated }}</td>
   252 :                                             <td> {{ powerfeed.available_power|divide:3 }} VA</td>
   253 :                                             {% with phase_available=powerfeed.available_power|divide:3 %}
   254 :                                                 <td>{% utilization_graph leg.allocated|percentage:phase_available %}</td>
   255 :                                             {% endwith %}
   256 :                                         </tr>
   257 :                                     {% endfor %}
   258 :                                 {% endwith %}
   259 :                             {% endfor %}
   260 :                         </table>
   261 :                     </div>
   262 :                 </div>


Traceback (most recent call last):
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/views/generic/base.py", line 84, in view
    return self.dispatch(request, *args, **kwargs)
  File "/opt/netbox/netbox/utilities/views.py", line 90, in dispatch
    return super().dispatch(request, *args, **kwargs)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/views/generic/base.py", line 119, in dispatch
    return handler(request, *args, **kwargs)
  File "/opt/netbox/netbox/netbox/views/generic/object_views.py", line 67, in get
    return render(request, self.get_template_name(), {
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/shortcuts.py", line 24, in render
    content = loader.render_to_string(template_name, context, request, using=using)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/loader.py", line 62, in render_to_string
    return template.render(context, request)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/backends/django.py", line 62, in render
    return self.template.render(context)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 175, in render
    return self._render(context)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/test/utils.py", line 111, in instrumented_test_render
    return self.nodelist.render(context)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in <listcomp>
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 958, in render_annotated
    return self.render(context)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/loader_tags.py", line 157, in render
    return compiled_parent._render(context)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/test/utils.py", line 111, in instrumented_test_render
    return self.nodelist.render(context)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in <listcomp>
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 958, in render_annotated
    return self.render(context)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/loader_tags.py", line 157, in render
    return compiled_parent._render(context)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/test/utils.py", line 111, in instrumented_test_render
    return self.nodelist.render(context)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in <listcomp>
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 958, in render_annotated
    return self.render(context)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/loader_tags.py", line 157, in render
    return compiled_parent._render(context)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/test/utils.py", line 111, in instrumented_test_render
    return self.nodelist.render(context)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in <listcomp>
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 958, in render_annotated
    return self.render(context)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/loader_tags.py", line 157, in render
    return compiled_parent._render(context)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/test/utils.py", line 111, in instrumented_test_render
    return self.nodelist.render(context)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in <listcomp>
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 958, in render_annotated
    return self.render(context)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/loader_tags.py", line 63, in render
    result = block.nodelist.render(context)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in <listcomp>
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 958, in render_annotated
    return self.render(context)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/loader_tags.py", line 63, in render
    result = block.nodelist.render(context)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in <listcomp>
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 958, in render_annotated
    return self.render(context)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/loader_tags.py", line 63, in render
    result = block.nodelist.render(context)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in <listcomp>
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 958, in render_annotated
    return self.render(context)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/defaulttags.py", line 322, in render
    return nodelist.render(context)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in <listcomp>
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 958, in render_annotated
    return self.render(context)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/defaulttags.py", line 238, in render
    nodelist.append(node.render_annotated(context))
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 958, in render_annotated
    return self.render(context)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/defaulttags.py", line 542, in render
    return self.nodelist.render(context)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in <listcomp>
    return SafeString("".join([node.render_annotated(context) for node in self]))
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 958, in render_annotated
    return self.render(context)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/defaulttags.py", line 238, in render
    nodelist.append(node.render_annotated(context))
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 958, in render_annotated
    return self.render(context)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1059, in render
    output = self.filter_expression.resolve(context)
  File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 739, in resolve
    new_obj = func(obj, *arg_vals)
  File "/opt/netbox/netbox/utilities/templatetags/helpers.py", line 131, in divide
    return round(x / y)

Exception Type: TypeError at /dcim/devices/79/
Exception Value: unsupported operand type(s) for /: 'str' and 'int'
Originally created by @baschdello on GitHub (Sep 1, 2022). Originally assigned to: @arthanson on GitHub. ### NetBox version v3.3.0 ### Python version 3.9 ### Steps to Reproduce 0. upgraded netbox to v3.3.0 2. click at an affected pdu (device) ### Expected Behavior I expect that the pdu device is displayed. ### Observed Behavior An error page with "TypeError" is thrown. Not every pdu is affected although of same device type. If deleting the cable of an affected pdu to the power feed, the pdu device is opened correctly. If I create the cable again, the type error page is present instead of the device page. With option "DEBUG = True" in configuration.py the type error page displays some helpful information (attached at bottom). I think there is something wrong at the power utilization graph because of type mismatch. ``` Template error: In template /opt/netbox/netbox/templates/dcim/device.html, error at line 252 unsupported operand type(s) for /: 'str' and 'int' 242 : {% else %} 243 : <td class="text-muted">&mdash;</td> 244 : <td class="text-muted">&mdash;</td> 245 : {% endif %} 246 : </tr> 247 : {% for leg in utilization.legs %} 248 : <tr> 249 : <td style="padding-left: 20px">Leg {{ leg.name }}</td> 250 : <td>{{ leg.outlet_count }}</td> 251 : <td>{{ leg.allocated }}</td> 252 : <td> {{ powerfeed.available_power|divide:3 }} VA</td> 253 : {% with phase_available=powerfeed.available_power|divide:3 %} 254 : <td>{% utilization_graph leg.allocated|percentage:phase_available %}</td> 255 : {% endwith %} 256 : </tr> 257 : {% endfor %} 258 : {% endwith %} 259 : {% endfor %} 260 : </table> 261 : </div> 262 : </div> Traceback (most recent call last): File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/core/handlers/exception.py", line 55, in inner response = get_response(request) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/core/handlers/base.py", line 197, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/views/generic/base.py", line 84, in view return self.dispatch(request, *args, **kwargs) File "/opt/netbox/netbox/utilities/views.py", line 90, in dispatch return super().dispatch(request, *args, **kwargs) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/views/generic/base.py", line 119, in dispatch return handler(request, *args, **kwargs) File "/opt/netbox/netbox/netbox/views/generic/object_views.py", line 67, in get return render(request, self.get_template_name(), { File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/shortcuts.py", line 24, in render content = loader.render_to_string(template_name, context, request, using=using) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/loader.py", line 62, in render_to_string return template.render(context, request) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/backends/django.py", line 62, in render return self.template.render(context) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 175, in render return self._render(context) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/test/utils.py", line 111, in instrumented_test_render return self.nodelist.render(context) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in render return SafeString("".join([node.render_annotated(context) for node in self])) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in <listcomp> return SafeString("".join([node.render_annotated(context) for node in self])) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 958, in render_annotated return self.render(context) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/loader_tags.py", line 157, in render return compiled_parent._render(context) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/test/utils.py", line 111, in instrumented_test_render return self.nodelist.render(context) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in render return SafeString("".join([node.render_annotated(context) for node in self])) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in <listcomp> return SafeString("".join([node.render_annotated(context) for node in self])) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 958, in render_annotated return self.render(context) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/loader_tags.py", line 157, in render return compiled_parent._render(context) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/test/utils.py", line 111, in instrumented_test_render return self.nodelist.render(context) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in render return SafeString("".join([node.render_annotated(context) for node in self])) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in <listcomp> return SafeString("".join([node.render_annotated(context) for node in self])) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 958, in render_annotated return self.render(context) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/loader_tags.py", line 157, in render return compiled_parent._render(context) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/test/utils.py", line 111, in instrumented_test_render return self.nodelist.render(context) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in render return SafeString("".join([node.render_annotated(context) for node in self])) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in <listcomp> return SafeString("".join([node.render_annotated(context) for node in self])) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 958, in render_annotated return self.render(context) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/loader_tags.py", line 157, in render return compiled_parent._render(context) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/test/utils.py", line 111, in instrumented_test_render return self.nodelist.render(context) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in render return SafeString("".join([node.render_annotated(context) for node in self])) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in <listcomp> return SafeString("".join([node.render_annotated(context) for node in self])) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 958, in render_annotated return self.render(context) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/loader_tags.py", line 63, in render result = block.nodelist.render(context) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in render return SafeString("".join([node.render_annotated(context) for node in self])) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in <listcomp> return SafeString("".join([node.render_annotated(context) for node in self])) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 958, in render_annotated return self.render(context) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/loader_tags.py", line 63, in render result = block.nodelist.render(context) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in render return SafeString("".join([node.render_annotated(context) for node in self])) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in <listcomp> return SafeString("".join([node.render_annotated(context) for node in self])) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 958, in render_annotated return self.render(context) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/loader_tags.py", line 63, in render result = block.nodelist.render(context) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in render return SafeString("".join([node.render_annotated(context) for node in self])) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in <listcomp> return SafeString("".join([node.render_annotated(context) for node in self])) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 958, in render_annotated return self.render(context) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/defaulttags.py", line 322, in render return nodelist.render(context) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in render return SafeString("".join([node.render_annotated(context) for node in self])) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in <listcomp> return SafeString("".join([node.render_annotated(context) for node in self])) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 958, in render_annotated return self.render(context) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/defaulttags.py", line 238, in render nodelist.append(node.render_annotated(context)) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 958, in render_annotated return self.render(context) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/defaulttags.py", line 542, in render return self.nodelist.render(context) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in render return SafeString("".join([node.render_annotated(context) for node in self])) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1000, in <listcomp> return SafeString("".join([node.render_annotated(context) for node in self])) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 958, in render_annotated return self.render(context) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/defaulttags.py", line 238, in render nodelist.append(node.render_annotated(context)) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 958, in render_annotated return self.render(context) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 1059, in render output = self.filter_expression.resolve(context) File "/opt/netbox-3.3.0/venv/lib/python3.9/site-packages/django/template/base.py", line 739, in resolve new_obj = func(obj, *arg_vals) File "/opt/netbox/netbox/utilities/templatetags/helpers.py", line 131, in divide return round(x / y) Exception Type: TypeError at /dcim/devices/79/ Exception Value: unsupported operand type(s) for /: 'str' and 'int' ```
adam added the type: bugstatus: accepted labels 2025-12-29 19:46:42 +01:00
adam closed this issue 2025-12-29 19:46:42 +01:00
Author
Owner

@jeremystretch commented on GitHub (Sep 1, 2022):

  1. upgraded netbox to v3.3.0
  2. click at an affected pdu (device)

I'm afraid that's not going to be sufficient to reproduce the reported behavior. Please try to determine steps that someone else can follow to reliably reproduce the issue.

Exception Type: TypeError at /dcim/devices/79/
Exception Value: unsupported operand type(s) for /: 'str' and 'int'

This indicates that powerfeed.available_power is being passed as a string. I'm not sure how that could happen, as available_power is a required PositiveIntegerField and can never be anything other than an integer.

@jeremystretch commented on GitHub (Sep 1, 2022): > 0. upgraded netbox to v3.3.0 > 1. click at an affected pdu (device) I'm afraid that's not going to be sufficient to reproduce the reported behavior. Please try to determine steps that someone else can follow to reliably reproduce the issue. ``` Exception Type: TypeError at /dcim/devices/79/ Exception Value: unsupported operand type(s) for /: 'str' and 'int' ``` This indicates that `powerfeed.available_power` is being passed as a string. I'm not sure how that could happen, as `available_power` is a required PositiveIntegerField and can never be anything other than an integer.
Author
Owner

@baschdello commented on GitHub (Sep 1, 2022):

Ok, I suspected that. I will see what I can do. I may need some time to figure out how to reproduce this.

@baschdello commented on GitHub (Sep 1, 2022): Ok, I suspected that. I will see what I can do. I may need some time to figure out how to reproduce this.
Author
Owner

@jeremystretch commented on GitHub (Sep 1, 2022):

I'm curious what the value of that field is for the affected power feed. Can you inspect it using the shell? (Grab the numeric ID of the feed first; in the example below it's 19.)

$ ./manage.py nbshell
### NetBox interactive shell (jstretch-workstation)
### Python 3.8.13 | Django 4.0.7 | NetBox 3.3.2-dev
### lsmodels() will show available models. Use help(<model>) for more info.
>>> PowerFeed.objects.get(pk=19)
<PowerFeed: P1-10A>
>>> PowerFeed.objects.get(pk=19).available_power
3520
@jeremystretch commented on GitHub (Sep 1, 2022): I'm curious what the value of that field is for the affected power feed. Can you inspect it using the shell? (Grab the numeric ID of the feed first; in the example below it's `19`.) ``` $ ./manage.py nbshell ### NetBox interactive shell (jstretch-workstation) ### Python 3.8.13 | Django 4.0.7 | NetBox 3.3.2-dev ### lsmodels() will show available models. Use help(<model>) for more info. >>> PowerFeed.objects.get(pk=19) <PowerFeed: P1-10A> >>> PowerFeed.objects.get(pk=19).available_power 3520 ```
Author
Owner

@baschdello commented on GitHub (Sep 5, 2022):

I've checked the PowerFeed but it seems that it is not a string:

./manage.py nbshell
### NetBox interactive shell (netbox-beta)
### Python 3.9.2 | Django 4.0.7 | NetBox 3.3.0
### lsmodels() will show available models. Use help(<model>) for more info.
>>> PowerFeed.objects.get(pk=49)
<PowerFeed: Feld01 - F04>
>>> PowerFeed.objects.get(pk=49).available_power
11085

So I've tried something other and played around with value "allocated draw" of the pdu's power port.
If opening page "Power Ports" of an affected pdu direct via url "/dcim/devices/[dev-id]/power-ports/" it seems that the power port has no allocated draw (displayed with a line). But if I edit this power port, adding for example 5 watts as allocated draw, the affected pdu is accessible without a type error page and device page is displayed like it should (except of this fictional allocated draw value).
I checked the nbshell in both cases:

  • case with non set allocated draw:
### NetBox interactive shell (netbox-beta)
### Python 3.9.2 | Django 4.0.7 | NetBox 3.3.0
### lsmodels() will show available models. Use help(<model>) for more info.
>>> d = Device.objects.get(pk=48)
>>> 
>>> p=d.powerports.get()
>>> p.get_power_draw()
{'allocated': 0, 'maximum': 5097, 'outlet_count': 24, 'legs': [{'name': 'A', 'allocated': 0, 'maximum': 1695, 'outlet_count': 8}, {'name': 'B', 'allocated': 0, 'maximum': 2002, 'outlet_count': 8}, {'name': 'C', 'allocated': 0, 'maximum': 1400, 'outlet_count': 8}]}
  • case with manually set allocated draw to 120W:
### NetBox interactive shell (netbox-beta)
### Python 3.9.2 | Django 4.0.7 | NetBox 3.3.0
### lsmodels() will show available models. Use help(<model>) for more info.
>>> d = Device.objects.get(pk=48)
>>> p=d.powerports.get()
>>> p.get_power_draw()
{'allocated': 120, 'maximum': 0, 'outlet_count': 24, 'legs': []}

In both cases I can not recognize any string values. I hope this information is helpful somehow.

@baschdello commented on GitHub (Sep 5, 2022): I've checked the PowerFeed but it seems that it is not a string: ``` ./manage.py nbshell ### NetBox interactive shell (netbox-beta) ### Python 3.9.2 | Django 4.0.7 | NetBox 3.3.0 ### lsmodels() will show available models. Use help(<model>) for more info. >>> PowerFeed.objects.get(pk=49) <PowerFeed: Feld01 - F04> >>> PowerFeed.objects.get(pk=49).available_power 11085 ``` So I've tried something other and played around with value "allocated draw" of the pdu's power port. If opening page "Power Ports" of an affected pdu direct via url "/dcim/devices/[dev-id]/power-ports/" it seems that the power port has no allocated draw (displayed with a line). But if I edit this power port, adding for example 5 watts as allocated draw, the affected pdu is accessible without a type error page and device page is displayed like it should (except of this fictional allocated draw value). I checked the nbshell in both cases: - case with non set allocated draw: ``` ### NetBox interactive shell (netbox-beta) ### Python 3.9.2 | Django 4.0.7 | NetBox 3.3.0 ### lsmodels() will show available models. Use help(<model>) for more info. >>> d = Device.objects.get(pk=48) >>> >>> p=d.powerports.get() >>> p.get_power_draw() {'allocated': 0, 'maximum': 5097, 'outlet_count': 24, 'legs': [{'name': 'A', 'allocated': 0, 'maximum': 1695, 'outlet_count': 8}, {'name': 'B', 'allocated': 0, 'maximum': 2002, 'outlet_count': 8}, {'name': 'C', 'allocated': 0, 'maximum': 1400, 'outlet_count': 8}]} ``` - case with manually set allocated draw to 120W: ``` ### NetBox interactive shell (netbox-beta) ### Python 3.9.2 | Django 4.0.7 | NetBox 3.3.0 ### lsmodels() will show available models. Use help(<model>) for more info. >>> d = Device.objects.get(pk=48) >>> p=d.powerports.get() >>> p.get_power_draw() {'allocated': 120, 'maximum': 0, 'outlet_count': 24, 'legs': []} ``` In both cases I can not recognize any string values. I hope this information is helpful somehow.
Author
Owner

@jaylik commented on GitHub (Sep 9, 2022):

@jeremystretch - We hit this bug with three phase power feeds. It seems that this line has a bug,

385a0f979e/netbox/templates/dcim/device.html (L232)

385a0f979e/netbox/templates/dcim/rack.html (L176)

385a0f979e/netbox/templates/dcim/powerfeed.html (L44-L53)

We monkey patched this with ugly solution:

diff --git a/netbox/templates/dcim/device.html b/netbox/templates/dcim/device.html
index 6cc8597495f16fb7be6ec0cb280655e54b756650..95b9ddf151c29356f9a61403cec92b7a3782a633 100644
--- a/netbox/templates/dcim/device.html
+++ b/netbox/templates/dcim/device.html
@@ -229,7 +229,7 @@
                                 <th>Utilization</th>
                             </tr>
                             {% for powerport in object.powerports.all %}
-                                {% with utilization=powerport.get_power_draw powerfeed=powerport.connected_endpoint %}
+                                {% with utilization=powerport.get_power_draw powerfeed=powerport.connected_endpoints.0 %}
                                     <tr>
                                         <td>{{ powerport }}</td>
                                         <td>{{ utilization.outlet_count }}</td>
diff --git a/netbox/templates/dcim/powerfeed.html b/netbox/templates/dcim/powerfeed.html
index 584454df85e9b1ad963959b77970df48e81c9774..f6f201336c4187119cf76937051936a678d1ce02 100644
--- a/netbox/templates/dcim/powerfeed.html
+++ b/netbox/templates/dcim/powerfeed.html
@@ -41,16 +41,18 @@
                     <tr>
                         <th scope="row">Connected Device</th>
                         <td>
-                            {% if object.connected_endpoint %}
-                                {{ object.connected_endpoint.device|linkify }} ({{ object.connected_endpoint }})
+                            {% with connected_endpoint=object.connected_endpoints.0 %}
+                            {% if connected_endpoint %}
+                                {{ connected_endpoint.device|linkify }} ({{ connected_endpoint }})
                             {% else %}
                                 {{ ''|placeholder }}
                             {% endif %}
+                            {% endwith %}
                         </td>
                     </tr>
                     <tr>
                         <th scope="row">Utilization (Allocated)</th>
-                        {% with utilization=object.connected_endpoint.get_power_draw %}
+                        {% with utilization=object.connected_endpoints.0.get_power_draw %}
                             {% if utilization %}
                                 <td>
                                     {{ utilization.allocated }}VA / {{ object.available_power }}VA
diff --git a/netbox/templates/dcim/rack.html b/netbox/templates/dcim/rack.html
index 51e873ffaf70a8d56596f99cb8367644fd2018a2..87ece4169d9252535776c4b7860e0fbaa3f8dc54 100644
--- a/netbox/templates/dcim/rack.html
+++ b/netbox/templates/dcim/rack.html
@@ -173,7 +173,7 @@
                                 <td>{{ powerfeed|linkify }}</td>
                                 <td>{% badge powerfeed.get_status_display bg_color=powerfeed.get_status_color %}</td>
                                 <td>{% badge powerfeed.get_type_display bg_color=powerfeed.get_type_color %}</td>
-                                {% with power_port=powerfeed.connected_endpoint %}
+                                {% with power_port=powerfeed.connected_endpoints.0 %}
                                     {% if power_port %}
                                         <td>{% utilization_graph power_port.get_power_draw.allocated|percentage:powerfeed.available_power %}</td>
                                     {% else %}
@jaylik commented on GitHub (Sep 9, 2022): @jeremystretch - We hit this bug with three phase power feeds. It seems that this line has a bug, https://github.com/netbox-community/netbox/blob/385a0f979ec460023d3d7f8e9003ddc373fb5ac3/netbox/templates/dcim/device.html#L232 https://github.com/netbox-community/netbox/blob/385a0f979ec460023d3d7f8e9003ddc373fb5ac3/netbox/templates/dcim/rack.html#L176 https://github.com/netbox-community/netbox/blob/385a0f979ec460023d3d7f8e9003ddc373fb5ac3/netbox/templates/dcim/powerfeed.html#L44-L53 We monkey patched this with ugly solution: ``` diff --git a/netbox/templates/dcim/device.html b/netbox/templates/dcim/device.html index 6cc8597495f16fb7be6ec0cb280655e54b756650..95b9ddf151c29356f9a61403cec92b7a3782a633 100644 --- a/netbox/templates/dcim/device.html +++ b/netbox/templates/dcim/device.html @@ -229,7 +229,7 @@ <th>Utilization</th> </tr> {% for powerport in object.powerports.all %} - {% with utilization=powerport.get_power_draw powerfeed=powerport.connected_endpoint %} + {% with utilization=powerport.get_power_draw powerfeed=powerport.connected_endpoints.0 %} <tr> <td>{{ powerport }}</td> <td>{{ utilization.outlet_count }}</td> diff --git a/netbox/templates/dcim/powerfeed.html b/netbox/templates/dcim/powerfeed.html index 584454df85e9b1ad963959b77970df48e81c9774..f6f201336c4187119cf76937051936a678d1ce02 100644 --- a/netbox/templates/dcim/powerfeed.html +++ b/netbox/templates/dcim/powerfeed.html @@ -41,16 +41,18 @@ <tr> <th scope="row">Connected Device</th> <td> - {% if object.connected_endpoint %} - {{ object.connected_endpoint.device|linkify }} ({{ object.connected_endpoint }}) + {% with connected_endpoint=object.connected_endpoints.0 %} + {% if connected_endpoint %} + {{ connected_endpoint.device|linkify }} ({{ connected_endpoint }}) {% else %} {{ ''|placeholder }} {% endif %} + {% endwith %} </td> </tr> <tr> <th scope="row">Utilization (Allocated)</th> - {% with utilization=object.connected_endpoint.get_power_draw %} + {% with utilization=object.connected_endpoints.0.get_power_draw %} {% if utilization %} <td> {{ utilization.allocated }}VA / {{ object.available_power }}VA diff --git a/netbox/templates/dcim/rack.html b/netbox/templates/dcim/rack.html index 51e873ffaf70a8d56596f99cb8367644fd2018a2..87ece4169d9252535776c4b7860e0fbaa3f8dc54 100644 --- a/netbox/templates/dcim/rack.html +++ b/netbox/templates/dcim/rack.html @@ -173,7 +173,7 @@ <td>{{ powerfeed|linkify }}</td> <td>{% badge powerfeed.get_status_display bg_color=powerfeed.get_status_color %}</td> <td>{% badge powerfeed.get_type_display bg_color=powerfeed.get_type_color %}</td> - {% with power_port=powerfeed.connected_endpoint %} + {% with power_port=powerfeed.connected_endpoints.0 %} {% if power_port %} <td>{% utilization_graph power_port.get_power_draw.allocated|percentage:powerfeed.available_power %}</td> {% else %} ```
Author
Owner

@baschdello commented on GitHub (Oct 13, 2022):

@jaylik Thank's for your monkey patch. I tried your device.html template patch. Now affected PDUs displayed properly without error page (I didn't check it with all affected PDUs, but checked two of them).

What I also tried without patching something: If I connect the power port of an PDU with a three-phase power feed, problem appears. Now if edit the power feed and switch to a single-phase type, the PDU is displayed without error page. As @jaylik already said, it seems that this problem appears at three-phase power feeds. What I can say, we mainly use three-phase feeds but I don't have this bug with all of our three-phase feeded PDUs.
Another try without patching something: if connecting the power port of affected PDU with two power feeds (possible since v3.3.0 because of the new cable model) the PDU is displayed properly. Both feeds are three-phase types.
Because this bug comes with upgrade to v3.3.0 I think it has something to do with the new cable model.

@baschdello commented on GitHub (Oct 13, 2022): @jaylik Thank's for your monkey patch. I tried your device.html template patch. Now affected PDUs displayed properly without error page (I didn't check it with all affected PDUs, but checked two of them). What I also tried without patching something: If I connect the power port of an PDU with a three-phase power feed, problem appears. Now if edit the power feed and switch to a single-phase type, the PDU is displayed without error page. As @jaylik already said, it seems that this problem appears at three-phase power feeds. What I can say, we mainly use three-phase feeds but I don't have this bug with all of our three-phase feeded PDUs. Another try without patching something: if connecting the power port of affected PDU with two power feeds (possible since v3.3.0 because of the new cable model) the PDU is displayed properly. Both feeds are three-phase types. Because this bug comes with upgrade to v3.3.0 I think it has something to do with the new cable model.
Author
Owner

@baschdello commented on GitHub (Oct 13, 2022):

What I can say, we mainly use three-phase feeds but I don't have this bug with all of our three-phase feeded PDUs.

I missed the fact, that our non-affected PDUs have a manually set allocated draw. If deleting the allocated draw of PDU power port, the exception page is present.

@baschdello commented on GitHub (Oct 13, 2022): > What I can say, we mainly use three-phase feeds but I don't have this bug with all of our three-phase feeded PDUs. I missed the fact, that our non-affected PDUs have a manually set allocated draw. If deleting the allocated draw of PDU power port, the exception page is present.
Author
Owner

@arthanson commented on GitHub (Nov 4, 2022):

@baschdello do you have a repro scenario for this? I tried using three-phase power feed and wasn't able to get it to repro. A step-by-step repro would be greatly appreciated.

@arthanson commented on GitHub (Nov 4, 2022): @baschdello do you have a repro scenario for this? I tried using three-phase power feed and wasn't able to get it to repro. A step-by-step repro would be greatly appreciated.
Author
Owner

@baschdello commented on GitHub (Nov 4, 2022):

I will try this on monday with a fresh installation of v3.3.0 and give feedback.

@baschdello commented on GitHub (Nov 4, 2022): I will try this on monday with a fresh installation of v3.3.0 and give feedback.
Author
Owner

@baschdello commented on GitHub (Nov 8, 2022):

I've reproduced this issue with a fresh installation of v3.3.0. Here are steps to reproduce:

  1. create site "dc1"
  2. create power-panel "usv-a"
  3. create rack "rack1" and assign it to site "dc1"
  4. create power-feed "feed1" with following details:
    Power Panel "usv-a"
    Rack "rack1"
    Phase "three-phase"
  5. create manufacturer "manufacturer1"
  6. create device-type "pdu" with manufacturer "manufacturer1"
  7. add power-port "Power" to device-type "pdu" with plug type "3P+N+E 6H"
  8. add power-outlets (one for each leg) "out1", "out2" and "out 3" with options:
    type "C13"
    power port "Power"
    feed leg "out1" => leg A, "out2" => leg B, "out 3" => leg C
  9. create devicerole "pdu"
  10. at our "rack1" create a pdu as non-racked device with the devicerole "pdu" and choose device-type "pdu"
  11. connect pdu power-port to power-feed and choose:
    Power Panel "USV-A"
    Power Feed "feed1"
  12. open the created device "pdu" and you will see the TypeError-page.

Best regards
baschdello

@baschdello commented on GitHub (Nov 8, 2022): I've reproduced this issue with a fresh installation of v3.3.0. Here are steps to reproduce: 1. create site "dc1" 2. create power-panel "usv-a" 3. create rack "rack1" and assign it to site "dc1" 4. create power-feed "feed1" with following details: Power Panel "usv-a" Rack "rack1" Phase "three-phase" 5. create manufacturer "manufacturer1" 6. create device-type "pdu" with manufacturer "manufacturer1" 7. add power-port "Power" to device-type "pdu" with plug type "3P+N+E 6H" 8. add power-outlets (one for each leg) "out1", "out2" and "out 3" with options: type "C13" power port "Power" feed leg "out1" => leg A, "out2" => leg B, "out 3" => leg C 9. create devicerole "pdu" 10. at our "rack1" create a pdu as non-racked device with the devicerole "pdu" and choose device-type "pdu" 11. connect pdu power-port to power-feed and choose: Power Panel "USV-A" Power Feed "feed1" 12. open the created device "pdu" and you will see the TypeError-page. Best regards baschdello
Author
Owner

@fabi125 commented on GitHub (Nov 28, 2022):

I don't think #10961 fully fixed the issue.

Here powerfeed is set using the removed connected_endpoint: https://github.com/netbox-community/netbox/pull/10961/files#diff-244731798e872e98b04c335c35679f920c3e5c90e8bf2340471f7910bd0449cdL232
Which means it will always be None.

I think the proper fix would be to change it to use connected_endpoints (plural).

There are also two other locations where connected_endpoint is still referenced:

b1da374df2/netbox/templates/dcim/interface.html (L213)

b1da374df2/netbox/templates/dcim/rack.html (L176)

@fabi125 commented on GitHub (Nov 28, 2022): I don't think #10961 fully fixed the issue. Here `powerfeed` is set using the removed `connected_endpoint`: https://github.com/netbox-community/netbox/pull/10961/files#diff-244731798e872e98b04c335c35679f920c3e5c90e8bf2340471f7910bd0449cdL232 Which means it will always be `None`. I think the proper fix would be to change it to use `connected_endpoints` (plural). There are also two other locations where `connected_endpoint` is still referenced: https://github.com/netbox-community/netbox/blob/b1da374df201a06daa90a3c462fafd42cfa6ed9b/netbox/templates/dcim/interface.html#L213 https://github.com/netbox-community/netbox/blob/b1da374df201a06daa90a3c462fafd42cfa6ed9b/netbox/templates/dcim/rack.html#L176
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#6921