Welcome to the Onshape forum! Ask questions and join in the discussions about everything Onshape.
First time visiting? Here are some places to start:- Looking for a certain topic? Check out the categories filter or use Search (upper right).
- Need support? Ask a question to our Community Support category.
- Please submit support tickets for bugs but you can request improvements in the Product Feedback category.
- 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.
Dual counterbore featurescript help throwing error but idk whats wrong

Hi All,
Starting with FS trying to stay positive but it seems like an uphill journey. Basically I want the same as the hole feature but I need a counterbore on both sides. I want to select the vertex/point and it will create a hole with the counterbore and then flip and do the same on the other side but as of now I cant even get a hole, and the error it throws does not really tell me anything? Help? Thanks !
For context I'm making parts that fit lego technic stuff trying to recreate "Catalog: Parts: Technic, Liftarm: 64179" (google and you will see)
FeatureScript 2559; import(path : "onshape/std/geometry.fs", version : "2559.0"); annotation { "Feature Type Name" : "Double Counterbore Hole", "Feature Type Description" : "Creates a hole with counterbores on both ends at a selected point" } export const doubleCounterboreHole = defineFeature(function(context is Context, id is Id, definition is map) precondition { annotation { "Name" : "Point", "Filter" : EntityType.VERTEX } definition.point is Query; annotation { "Name" : "Hole Diameter", "Min" : 1, "Max" : 100, "Default" : 4.9} isLength(definition.holeDiameter, { (millimeter) : [1, 5.0, 100] } as LengthBoundSpec); annotation { "Name" : "Hole Depth", "Min" : 1, "Max" : 100, "Default" : 8.0 } isLength(definition.holeDepth, { (millimeter) : [1, 10.0, 100] } as LengthBoundSpec); annotation { "Name" : "Counterbore Diameter", "Min" : 1, "Max" : 100, "Default" : 6.2 } isLength(definition.counterboreDiameter, { (millimeter) : [1, 8.0, 100] } as LengthBoundSpec); annotation { "Name" : "Counterbore Depth", "Min" : 0.1, "Max" : 100, "Default" : 0.8 } isLength(definition.counterboreDepth, { (millimeter) : [0.1, 2.0, 100] } as LengthBoundSpec); } { //const pointPosition = evVertexPoint(context, { "vertex" : definition.point }); // Define the hole parameters var holeDefinition = { "position" : definition.point, "diameter" : definition.holeDiameter, "depth" : definition.holeDepth, "counterboreDiameter" : definition.counterboreDiameter, "counterboreDepth" : definition.counterboreDepth, "flip" : false }; // Create the hole hole(context, id + "hole", holeDefinition); // Create the flipped hole for the counterbore on the other end //holeDefinition.flip = true; //hole(context, id + "flippedHole", holeDefinition); });
and this is the error I get
throw Execution error
78:21
onshape/std/feature.fs (defineFeature)
40:9
HoleTwoCounterbore (const doubleCounterboreHole)
57:17
onshape/std/feature.fs (defineFeature)
Part Studio 2 (Double Counterbore Hole 1)
Part Studio 2
Precondition failed (definition.locations is Query)
369:9
onshape/std/hole.fs (const hole)
57:17
onshape/std/feature.fs (defineFeature)
40:9
HoleTwoCounterbore (const doubleCounterboreHole)
57:17
onshape/std/feature.fs (defineFeature)
Part Studio 2 (Double Counterbore Hole 1)
Part Studio 2
Comments
If you look at the hole feature it requires a field called "locations" as a query.
You are using "position" which is not a field in the hole feature.
Custom FeatureScript and Onshape Integrated Applications
It may be easier to call opHole in your feature, something like this…
In your feature do you intend to always have the same counterbore depth/diam for start and end of hole. That's what I assumed above ^^^
The hole feature is a tricky one to wrap one's head around, but it can be very powerful once you do! I hacked this together quickly.
@GregBrown
Thank you so much that's great, I wish you would have shared a bit more of your code because I'm still lost on my own :)
That's basically exactly what I'm trying to do, but what I'm doing is even simpler because the depth, and diameters are always constant.
Basically my issue now is I don't know how to make:
I was thinking the holepositionreference was a point, and the holelocation/direction were a point and a line and the "targets" was the body, but that did not work.
I'm wanting to just select a point and a line as the direction and it will make the dual counterbore at 8mm spacing along the line for n instances.
Edit: Working on this I figured out the holepositionref and the first error I needed units on counterboredia
Edit: I think I got a bit further, not sure what hole_no_hits means? I google and get nothing, where are the docs?
This is the error I get ?
Thinking through this and working on it I got holes all over the place but never really normal to the point. I think the best way to do this is just that a user selects a face, the fs will calculate the center of that face and generate the dualcounterbore holes at 8mm intervals from center to each side.
Also could someone please point me at the docs for ophole, I cannot find a single example online and chatgpt is clueless. I would expect there is online documentation with examples of how to use the function. Basically every function takes a "definition" which does not help me because that's an object and we dont know what's in the object.
Thanks!
The documentation is here:
https://cad.onshape.com/FsDoc/library.html#opHole-Context-Id-map
You might need to follow some of the links to dig one level further into the types, eg. HoleDefinition https://cad.onshape.com/FsDoc/library.html#HoleDefinition
Here is a rough redo of your code:
https://cad.onshape.com/documents/094f8898e036922eb050009b/w/6ca25cb8756081fe90a9ffcb/e/7506a4da25f351526d0fa470
I kept a lot of what you had posted, but I did have to make a number of changes. I did not restructure it as much as I would have for my own feature, but I did use some artistic license with the selections. Have a look at how I used Mate connectors for the location (it also allows you to select a sketch point..)
Also:
There are many, many more things to optimize here, but perhaps this will get you started. Particularly in patterning there are a million different approaches. I am not sure what your intent is, but again, use this and the docs and experiment. Folks here will probably happily weigh in on how to do this properly :)
Again stellar answer thank you Greg! I like the way you did things. I eventually got things to work. I tried to keep it as simple as possible and basically allow it to poke a hole (dual counter bore) that fits the lego pieces perfect given the holeDefinition. This way I can just put points all over where I want to be able to poke lego pats in and then I just select the ones I want to have holes in.
This way I dont have to deal with the direction of the holes and updating the vertex as I go in the for loop. I can just do a linear pattern of points and then select the ones I want to turn into lego holes.
I could probably do this a lot better but it's pretty hard for me to understand everything. The library documentation was very helpful. Also just keeping the tools allowed me to see where they were when I was messing up the normal. If I wanted to make this better I would make all the user elements configurable and get the script to figure out where to put the points spacing them every or every other and stopping at the end of the body.
I tried to do a bunch of stuff to get the body the point was on and get the face the point was on allowing the user to just select the point, I should be able to get the body and the face from the point right? But it never worked for me.
FeatureScript 2559;
import(path : "onshape/std/common.fs", version : "2559.0");
import(path : "onshape/std/hole.fs", version : "2559.0");
Adding a bit to this I was able to keep the tool and use it to make a "post" instead of a hole, so you can fit lego pieces. Not perfect but I thought it might be of interest to anyone who finds this discussion.
FeatureScript 2559;
import(path : "onshape/std/common.fs", version : "2559.0");
import(path : "onshape/std/hole.fs", version : "2559.0");
annotation {
"Feature Type Name" : "Lego Hole Creator",
"Feature Type Description" : "Creates lego compatible holes across face"
}
export const legoHole = defineFeature(function(context is Context, id is Id, definition is map)
precondition
{
annotation { "Name" : "body", "Filter" : EntityType.BODY }
definition.body is Query;
annotation { "Name" : "Face", "Filter" : EntityType.FACE }
definition.face is Query;
annotation { "Name" : "Start point", "Filter" : EntityType.VERTEX }
definition.points is Query;
}
{
// const stuff related to the hole profile (defined by lego)
const holeDiameter = 5.0 * millimeter; // Hole diameter
const holeDepth = (7.8-1.6) * millimeter; // Depth of the hole
const counterBoreDepth = 0.8 * millimeter;
const counterBoreDiameter = 6.2 * millimeter;
const totalDepth = 7.8 * millimeter;
annotation {
"Feature Type Name" : "Lego Post Creator",
"Feature Type Description" : "Creates lego compatible Post across face"
}
export const legoPost = defineFeature(function(context is Context, id is Id, definition is map)
precondition
{
annotation { "Name" : "body", "Filter" : EntityType.BODY }
definition.body is Query;
annotation { "Name" : "Face", "Filter" : EntityType.FACE }
definition.face is Query;
annotation { "Name" : "Start point", "Filter" : EntityType.VERTEX }
definition.points is Query;
annotation { "Name" : "Opposite direction", "UIHint" : UIHint.OPPOSITE_DIRECTION }
definition.doOpposite is boolean;
}
{
// const stuff related to the hole profile (defined by lego)
const holeDiameter = 5.0 * millimeter; // Hole diameter
const holeDepth = (7.8-1.6) * millimeter; // Depth of the hole
const counterBoreDepth = 0.8 * millimeter;
const counterBoreDiameter = 6.2 * millimeter;
const totalDepth = (7.8 + 0.25) * millimeter;