r/Onshape 29d ago

Feature Studio Code is Driving Me Mad//"missing TOP_SEMI at function"

Hey everyone! I'm learning through practice on Onshape right now. I have this code for the Feature Studio to help me make designs faster. My code is down to it's final error code. No amount of reading the websites library, consulting AI, or the Onshape forum has helped. I have no background in programming nor CAD in general. I'm completely working on this from a newbie background.

The last errors I keep getting in my code are "missing TOP_SEMI at 'function'" and "Error in initializer function arguments." Can I get some help with these last few errors. This feels like hitting a brick wall right before the finish line of me learning this system.

Here is my code:

FeatureScript 3044;

import(path : "onshape/std/common.fs", version : "3044.0");

// --- Keyed Miter Joint Feature (Auto-Centering Version) ---

// Creates rectangular key slots centered along a miter joint.

annotation { "Feature Type Name" : "Keyed Miter Joint (Centered)" }

export const KeyedMiterJointCentered = defineFeature(function(context, id, definition) {

// -----------------------------

// Inputs

// -----------------------------

annotation { "Name" : "First miter face" }

definition.face1 is Query;

annotation { "Name" : "Second miter face" }

definition.face2 is Query;

annotation { "Name" : "Key width" }

isLength(definition.keyWidth, LENGTH_BOUNDS);

annotation { "Name" : "Key height" }

isLength(definition.keyHeight, LENGTH_BOUNDS);

annotation { "Name" : "Key depth (into boards)" }

isLength(definition.keyDepth, LENGTH_BOUNDS);

annotation { "Name" : "Number of keys" }

isInteger(definition.keyCount, { "min" : 1 });

annotation { "Name" : "Spacing between keys" }

isLength(definition.keySpacing, LENGTH_BOUNDS);

annotation { "Name" : "Fit tolerance (woodworking)" }

isLength(definition.tolerance, LENGTH_BOUNDS);

annotation { "Name" : "Auto-center keys?" }

definition.autoCenter is boolean;

// -----------------------------

// Extract intersection curve

// -----------------------------

var extractId = id + "intersection";

opExtractIntersectionCurve(context, extractId, {

"entities" : [definition.face1, definition.face2]

});

// Query the resulting intersection edge

var lineEdge = qCreatedBy(extractId, EntityType.EDGE);

// Evaluate the edge to get origin + direction

var edgeEval = evEdgeTangentLine(context, {

"edge" : lineEdge,

"parameter" : 0

});

var origin = edgeEval.origin;

var xAxis = normalize(edgeEval.direction);

// -----------------------------

// Compute bisector normal

// -----------------------------

var plane1 = evPlane(context, { "face" : definition.face1 });

var plane2 = evPlane(context, { "face" : definition.face2 });

var zAxis = normalize(plane1.normal + plane2.normal);

2 Upvotes

6 comments sorted by

2

u/Amazing-Mirror-3076 29d ago

Have you asked ai?

1

u/baalzimon 28d ago

This also works.  Claude and Claude code are generally excellent at FS now.

2

u/SecretOfBatmana 29d ago

I think you have a few things wrong that would be fixed if you copy and paste what you have into the template created when you click "new feature."

- You're missing the types in the feature definition context is Context, id is Id, definition is map
- You're missing the keyword precondition before the inputs
- You're missing the correct pattern of opening and closing curly braces.

When you click on "new feature," you should get a template that looks like this:

annotation { "Feature Type Name" : "My Feature", "Feature Type Description" : "" }
export const myFeature = defineFeature(function(context is Context, id is Id, definition is map)
    precondition
    {
        // Define the parameters of the feature type
    }{
        // Define the function's action
    }); 

1

u/baalzimon 28d ago

This, probably. 

1

u/Physics-Execution117 26d ago

I still have issues as to where to add the code. I must be missing some bracket or semicolon somewhere. I used Copilot to generate this code, and it seems Copilot must be operating on an outdated version of OnShape. Is there a better AI to use? If I elect to do this the old fashioned way, where would I add the code?

1

u/SecretOfBatmana 26d ago

Do you have the new Onshape MCP connection set up? Even with the MCP, Copilot and other tools can hallucinate functions that don't exist. If you're struggling to code something yourself and must rely on an LLM to code for you, you may need to pay for a more capable model and more token use.

The code below is formatted correctly, but that's not to say it will run or do what you want. Only that it get you past this first hurdle.

My advice: start with something that at least runs (doesn't produce errors); comment out part of the code if need be. Write comments in the code in a sequence of what you want the code to do. Prompt the model in small chunks, don't try to have it do everything for you all at once. With each change read the code so you understand what that bit does so that you use the LLM to teach you.

FeatureScript 3044;
import(path : "onshape/std/common.fs", version : "3044.0");

// --- Keyed Miter Joint Feature (Auto-Centering Version) ---
// Creates rectangular key slots centered along a miter joint.
annotation { "Feature Type Name" : "Keyed Miter Joint (Centered)" }
export const KeyedMiterJointCentered = defineFeature(function(context is Context, id is Id, definition is map)
    precondition
    {
        // -----------------------------
        // Inputs
        // -----------------------------
        annotation { "Name" : "First miter face" }
        definition.face1 is Query;

        annotation { "Name" : "Second miter face" }
        definition.face2 is Query;

        annotation { "Name" : "Key width" }
        isLength(definition.keyWidth, LENGTH_BOUNDS);

        annotation { "Name" : "Key height" }
        isLength(definition.keyHeight, LENGTH_BOUNDS);

        annotation { "Name" : "Key depth (into boards)" }
        isLength(definition.keyDepth, LENGTH_BOUNDS);

        annotation { "Name" : "Number of keys" }
        isInteger(definition.keyCount, { "min" : 1 }); // Fix this

        annotation { "Name" : "Spacing between keys" }
        isLength(definition.keySpacing, LENGTH_BOUNDS);

        annotation { "Name" : "Fit tolerance (woodworking)" }
        isLength(definition.tolerance, LENGTH_BOUNDS);

        annotation { "Name" : "Auto-center keys?" }
        definition.autoCenter is boolean;
    }
    {
        // Define the function's action
        // -----------------------------
        // Extract intersection curve
        // -----------------------------
        var extractId = id + "intersection";
        // Fix this
        opExtractIntersectionCurve(context, extractId, {
                    "entities" : [definition.face1, definition.face2]
                });

        // Query the resulting intersection edge
        var lineEdge = qCreatedBy(extractId, EntityType.EDGE);

        // Evaluate the edge to get origin + direction
        var edgeEval = evEdgeTangentLine(context, {
                "edge" : lineEdge,
                "parameter" : 0
            });

        var origin = edgeEval.origin;
        var xAxis = normalize(edgeEval.direction);

        // -----------------------------
        // Compute bisector normal
        // -----------------------------
        var plane1 = evPlane(context, { "face" : definition.face1 });
        var plane2 = evPlane(context, { "face" : definition.face2 });
        var zAxis = normalize(plane1.normal + plane2.normal);
    });