Welcome to the Onshape forum! Ask questions and join in the discussions about everything Onshape.

First time visiting? Here are some places to start:

  1. Looking for a certain topic? Check out the categories filter or use Search (upper right).
  2. Need support? Ask a question to our Community Support category.
  3. Please submit support tickets for bugs but you can request improvements in the Product Feedback category.
  4. Be respectful, on topic and if you see a problem, Flag it.

If you would like to contact our Community Manager personally, feel free to send a private message or an email.

Debugging featurescript failures and exceptions

stixpjrstixpjr Member Posts: 8
I've using onshape for a while, designing various models for 3d printing, mostly to learn, for fun & curiosity. I've toyed with featurescript a little, but I'm finding some failures hard to debug. Currently, I have a "jigsaw" script which generates a cut-like childrens jigsaw (yes, this works remarkably well 3d printed). However, if I alter the size, gap, try "randomly" reversing the joiners, I get a variety of exceptions, the main two being:




This obviously isn't really a purpose that onshape was designed to cope with, but it performs remarkably well, considering my creative abuse. Any suggestions to debug this further?

The shared example is:


  • Jake_RosenfeldJake_Rosenfeld Moderator, Onshape Employees, Developers Posts: 1,466
    @stixpjr I would suspect that both of these issues arise from passing in bad input entities into opExtrude or opThicken.  Extrude requires faces or edges as input, and thicken takes faces or sheet bodies.  A good first step would be to add a:
    debug(context, extrudeEntities); // extrudeEntities is the Query you intend to pass into extrude
    before the extrude, and see what it highlighted/printed to the console.

    If you do that for one of the failing cases, and it looks like you are trying to extrude the correct entity, please feel free to post here again, and we can look into it more closely.
    Jake Rosenfeld - Modeling Team
  • stixpjrstixpjr Member Posts: 8
    Ok, that highlighted a bug (sketch edges overlapping, causing the failed extrude).
    After fixing that, now I just get the "throw THICKEN_FAILED". Debug output is:
    debug: Query resolves to 4 bodies (4 sheet)
    which looks sane?
  • Jake_RosenfeldJake_Rosenfeld Moderator, Onshape Employees, Developers Posts: 1,466

    Couple things to try:

    First I would try doing each body individually, to see if one specific body is the problem:
    int i = -1;
    for (var sheetBody in evaluateQuery(context, sheetBodies))
        i += 1;
            const thickenId = id + i + thicken;
            opThicken(context, thickenId, {
                ... thicken definition with `sheetBody` as the entity to thicken
            debug(context, qCreatedBy(thickenId, EntityType.BODY)); // this will show all the successful thickens in red
            println("Thicken " ~ i ~ " was successful");
            debug(context, sheetBody); // this will show all the unsuccessful thicken inputs in red.
            println("Thicken " ~ i ~ "failed");
    You probably only want to have one of those debugs on at a time so you can piece out which thicken is failing.

    Something else worth trying is:
    const facesToThicken = qOwnedByBody(sheetBodies, EntityType.FACE);
    and trying to thicken the faces rather than the bodies.  You can also run the faces through the same loop from above too see if there is one or a few specific problem faces.

    If you can make a Version of your document where this failure is occurring, and then post the link to that Version, it would be easy to look into.
    Jake Rosenfeld - Modeling Team
  • stixpjrstixpjr Member Posts: 8
    Thanks for your suggestions - I've tried looping over the query entities, adding the exception handling, and trying to thicken just the faces, but I still get exceptions thrown, depending on the parameters chosen - "random joiner direction" seems to trigger most reliably. I also split the "thicken" into opThicken and opBoolean, for extra visibility.

    Nothing strange in the debug output:
    debug: *** thicken failed, entity:
    debug: Query resolves to 1 face
    And the rendered face looks OK on screen.

    The following is tied to a failing version:
  • Jake_RosenfeldJake_Rosenfeld Moderator, Onshape Employees, Developers Posts: 1,466

    I wouldn't expect to be able to thicken a shape like this very much because it will quickly become self intersecting at the sharp corners:

    I am brainstorming some solutions for how you may be able to achieve what you want, but the simplest solution would to just be to soften the turn where the bump meets the rest of the piece.  Are you working with a strict set of parameters, or could this shape be drawn a little differently?  To test out whether this is the case, I suspect that if you turn down the gap to be low enough (without changing the geometry), there is probably some threshold where the thicken will start to succeed.
    Jake Rosenfeld - Modeling Team
  • stixpjrstixpjr Member Posts: 8
    Indeed, tweaking the shape to soften the curve a little makes it succeed. I'm a little surprised by the behaviour, however - it successfully thickened several other rotations of the same curve - 21 other instances, apparently. There shouldn't be any difference between those 3 and the others except rotation and translation (ok, mirroring, too).

    Interestingly, when I try to etch a spiral in the top surface, 0.5mm of the 2mm thickness, again, a thicken operation fails. This is not featurescript, just regular onshape objects and operations:
  • Jake_RosenfeldJake_Rosenfeld Moderator, Onshape Employees, Developers Posts: 1,466

    It is the boolean postprocessing that is failing, not the thicken itself.  If you switch to NEW it should probably work.

    As to why the boolean is failing, it looks like we are doing some highlighting to point out the problem area:

    It might be that the cut creates some non-manifold geometry in there, or possibly just that there is a bug in our geometry kernel.  Is this etching intended as part of the final design, or just playing around to see when thicken fails or succeeds?
    Jake Rosenfeld - Modeling Team
  • Jake_RosenfeldJake_Rosenfeld Moderator, Onshape Employees, Developers Posts: 1,466
    One thing I've noticed is that there are lots of these little slivers of geometry on the parts along the outer border:

    These slivers may be causing some instability.
    Jake Rosenfeld - Modeling Team
  • stixpjrstixpjr Member Posts: 8
    Yes, I'm just playing around :)

    However, it seems useful to shake out the flaky behaviour - if I'm finding flakes, I'm sure more serious users may also be finding these.

    Given the geometry here, I can't see how there's non-manifold geometry created - but floating point math is hard!

    I previously noticed the slivers on the end of the thickened splines; given what the thicken op does, these make sense - I can also see why this might be causing some instability. Relatedly: I only just discovered sketch slots - these seem to be a useful way to avoid thicken entirely, and have sane behavior on the spline ends. However, I haven't found a FeatureScript API to this function?
  • Jake_RosenfeldJake_Rosenfeld Moderator, Onshape Employees, Developers Posts: 1,466
    There is no FeatureScript skSlot, correct.  But it would not be too hard to write one :) :
    function skSlot(sketch is Sketch, id is string, pt1 is Vector, pt2 is Vector, diameter is ValueWithUnits)
        const pt1ToPt2 = normalize(pt2 - pt1);
        const push1 = vector(-pt1ToPt2[1], pt1ToPt2[0]);
        const push2 = vector(pt1ToPt2[1], -pt1ToPt2[0]);
        const radius = diameter / 2;
        const pt1Pushed = [
                pt1 + push1 * radius,
                pt1 + push2 * radius
        const pt2Pushed = [
                pt2 + push1 * radius,
                pt2 + push2 * radius
        // Semicircle around pt1
        skArc(sketch, id ~ ".pt1Arc", {
                    "start" : pt1Pushed[0],
                    "mid" : pt1 - pt1ToPt2 * radius,
                    "end" : pt1Pushed[1]
        // Semicircle around pt2
        skArc(sketch, id ~ ".pt2Arc", {
                    "start" : pt2Pushed[0],
                    "mid" : pt2 + pt1ToPt2 * radius,
                    "end" : pt2Pushed[1]
        // Lines connecting semicircles
        skLineSegment(sketch, id ~ ".line1", {
                    "start" : pt1Pushed[0],
                    "end" : pt2Pushed[0]
        skLineSegment(sketch, id ~ ".line2", {
                    "start" : pt1Pushed[1],
                    "end" : pt2Pushed[1]


    Jake Rosenfeld - Modeling Team
  • stixpjrstixpjr Member Posts: 8

    However, the built-in slot sketch tool also copes with splines as input - which require more than just a linear offset. I had originally thought that it would require offsetting each spline control point by the radius normal to the spline (at that point) - but that is too simplistic, and the transformation is deeper than that.
  • stixpjrstixpjr Member Posts: 8
    Ha, I think I've found what I need. Too late now to concentrate, but there's some nice FeatureScript code snippets under "Offset Curves, Using Onshape Constraints": https://www.onshape.com/cad-blog/everything-you-ever-wanted-to-know-about-onshape-splines-part-2-of-2
  • stixpjrstixpjr Member Posts: 8
    Ok, based on that doc and also looking at the generated code from a sketch slot based on a spline, I've tried adding various constraints to generate my own slot programmatically, but almost any combination just generates errors of the form:
    Onshape encountered a problem with your last operation. If the problem persists, please contact support. Support code 93aa18d7efc1f4b37e50921f.
    I'm guessing the solver is unable to successfully solve based on the constraints. skConstraint is barely documented, given that it's mostly unnecessary, which makes it hard to debug. I also notice that the generated code includes a large blob of consts passed to skSetInitialGuess (undocumented) which likely helps the solver on its way.
Sign In or Register to comment.