Summary
union() is rejected when one operand is a sweep() result and the other is an
extrude(). The practical consequence is that a helical thread cannot be unioned into
the shank it belongs to, so a threaded fastener cannot exist as a single solid.
engine: The Zoo engine cannot handle this 3D union yet. Please report this as an issue
The error text asks for a report, hence this issue.
Minimal repro
Two bodies. One extrude, one sweep along a helix(). Nothing else.
@settings(defaultLengthUnit = in, kclVersion = 2.0)
shank = startSketchOn(XY)
|> circle(center = [0, 0], radius = 0.1875)
|> extrude(length = 0.44)
th = helix(angleStart = 0, ccw = true, revolutions = 8, length = 0.43, radius = 0.21875, axis = Z)
ridge = startSketchOn(XZ)
|> startProfile(at = [0.1875, 0.005])
|> line(end = [0.03125, 0.022])
|> line(end = [-0.03125, 0.022])
|> close()
|> sweep(path = th)
threadedStud = union([shank, ridge]) // rejected
Both operands build fine individually and render correctly as separate bodies. Only the
union is refused.
Same rejection with a loft operand
union([loft, extrude]) fails identically:
lo = startSketchOn(offsetPlane(XY, offset = 0.70)) |> circle(center = [0,0], radius = 0.19)
hi = startSketchOn(offsetPlane(XY, offset = 0.83)) |> circle(center = [0,0], radius = 0.31)
cone = loft([lo, hi])
body = startSketchOn(XY) |> circle(center = [0,0], radius = 0.19) |> extrude(length = 0.80)
joined = union([cone, body]) // rejected
This blocks flare seats, chamfer transitions and tapered hoods being joined to the
prismatic bodies they adjoin. It may or may not share a root cause with the sweep case,
but the symptom and error string are identical, so both are reported here rather than
split across two issues.
Impact
This is not cosmetic. Downstream of the sweep case:
- a male thread cannot exist as one solid;
- therefore a male/female thread pair cannot be evaluated for mesh or interference at
all;
- so any threaded-fastener assembly is reduced to cosmetic thread geometry plus a plain
bore, and must be labelled as such rather than presented as a validated joint.
We hit this building AN-4 and AN-6 flared-fitting assemblies (37 degree aviation flare
hardware). The thread is currently carried as a separate body with an explicit
"cosmetic thread representation" notice in the source, because there is no honest
alternative.
#1294 reports the same engine
message on subtract() with cut-crossing tools and absolute-scale sensitivity. Further
measurement since then suggests the boolean limits are governed by resulting topology
rather than operand count, which may be useful triage context:
| Case |
Operands |
Result |
| 78 circular cutters subtracted from one body, single call |
78 |
works |
| 2 cutters subtracted from a flange plate |
2 |
works |
| 2 cutters whose diameter exceeds the bar thickness (cut would sever the body) |
2 |
rejected |
| 2 cutters + 1 window cutter that would turn a plate into a closed frame |
3 |
rejected |
| 1 extrude + 1 sweep (this issue) |
2 |
rejected |
78 cutters in a single call succeeding while 2 fail is the part that seems worth
knowing: quantity is clearly not the variable.
Environment
- KCL
@settings(kclVersion = 2.0), default length unit in
- Driven through the
zoo-mcp server (mock_execute_kcl, execute_kcl,
snapshot_of_kcl)
- Reproduced repeatedly on 2026-07-30 and 2026-07-31
Note on mock execution
mock_execute_kcl returns success for both repros above before the engine rejects
them. If mock is intended as a pre-flight check, it does not currently cover this class
of failure - worth flagging separately if that is a surprise.
Suggested
Short term, a "known limitations" note on the
union() standard library page
covering operand kinds that are not yet supported would save the discovery hunt - the
same gap #1294 identifies for subtract().
Summary
union()is rejected when one operand is asweep()result and the other is anextrude(). The practical consequence is that a helical thread cannot be unioned intothe shank it belongs to, so a threaded fastener cannot exist as a single solid.
The error text asks for a report, hence this issue.
Minimal repro
Two bodies. One extrude, one sweep along a
helix(). Nothing else.Both operands build fine individually and render correctly as separate bodies. Only the
union is refused.
Same rejection with a loft operand
union([loft, extrude])fails identically:This blocks flare seats, chamfer transitions and tapered hoods being joined to the
prismatic bodies they adjoin. It may or may not share a root cause with the sweep case,
but the symptom and error string are identical, so both are reported here rather than
split across two issues.
Impact
This is not cosmetic. Downstream of the sweep case:
all;
bore, and must be labelled as such rather than presented as a validated joint.
We hit this building AN-4 and AN-6 flared-fitting assemblies (37 degree aviation flare
hardware). The thread is currently carried as a separate body with an explicit
"cosmetic thread representation" notice in the source, because there is no honest
alternative.
Related: #1294
#1294 reports the same engine
message on
subtract()with cut-crossing tools and absolute-scale sensitivity. Furthermeasurement since then suggests the boolean limits are governed by resulting topology
rather than operand count, which may be useful triage context:
78 cutters in a single call succeeding while 2 fail is the part that seems worth
knowing: quantity is clearly not the variable.
Environment
@settings(kclVersion = 2.0), default length unitinzoo-mcpserver (mock_execute_kcl,execute_kcl,snapshot_of_kcl)Note on mock execution
mock_execute_kclreturns success for both repros above before the engine rejectsthem. If mock is intended as a pre-flight check, it does not currently cover this class
of failure - worth flagging separately if that is a surprise.
Suggested
Short term, a "known limitations" note on the
union()standard library pagecovering operand kinds that are not yet supported would save the discovery hunt - the
same gap #1294 identifies for
subtract().