How to fix 'ValueError: No pending wires present' when extruding a face in CadQuery

Problem:

You are trying to extrude an existing face using CadQuery (cq) using code similar to

import cadquery as cq

box = cq.Workplane("XY").box(1, 1, 1)

face_to_extrude = box.faces(">Z")

result = face_to_extrude.extrude(2, taper=45)

But when you try to run this, you see the following error message:

{
    "name": "ValueError",
    "message": "No pending wires present",
    "stack": "---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[3], line 7
      3 box = cq.Workplane(\"XY\").box(1, 1, 1)
      5 face_to_extrude = box.faces(\">Z\")
----> 7 result = face_to_extrude.extrude(2, taper=45)

File /usr/local/lib/python3.10/dist-packages/cadquery/cq.py:3078, in Workplane.extrude(self, until, combine, clean, both, taper)
   3075     r = self._extrude(None, both=both, taper=taper, upToFace=until)
   3077 elif isinstance(until, (int, float)):
-> 3078     r = self._extrude(until, both=both, taper=taper, upToFace=None)
   3080 elif isinstance(until, (str, Face)) and combine is False:
   3081     raise ValueError(
   3082         \"`combine` can't be set to False when extruding until a face\"
   3083     )

File /usr/local/lib/python3.10/dist-packages/cadquery/cq.py:3676, in Workplane._extrude(self, distance, both, taper, upToFace, additive)
   3673     return facesList
   3675 # process sketches or pending wires
-> 3676 faces = self._getFaces()
   3678 # check for nested geometry and tapered extrusion
   3679 for face in faces:

File /usr/local/lib/python3.10/dist-packages/cadquery/cq.py:3624, in Workplane._getFaces(self)
   3621         rv.extend(el)
   3623 if not rv:
-> 3624     rv.extend(wiresToFaces(self.ctx.popPendingWires()))
   3626 return rv

File /usr/local/lib/python3.10/dist-packages/cadquery/cq.py:129, in CQContext.popPendingWires(self, errorOnEmpty)
    123 \"\"\"
    124 Get and clear pending wires.
    125 
    126 :raises ValueError: if errorOnEmpty is True and no wires are present.
    127 \"\"\"
    128 if errorOnEmpty and not self.pendingWires:
--> 129     raise ValueError(\"No pending wires present\")
    130 out = self.pendingWires
    131 self.pendingWires = []

ValueError: No pending wires present"

Solution

Use

face_to_extrude.wires().toPending().extrude(...)

which will create pending wires from the selected face.

Full example:

import cadquery as cq

box = cq.Workplane("XY").box(1, 1, 1)

face_to_extrude = box.faces(">Z")

result = face_to_extrude.wires().toPending().extrude(2, taper=45)