Objective: Validate the main branch model exist and retrieving the main model to push data to that branch
Issue:
I have created a new project and before publishing data to the project main model, I want to make sure the branchname exist. However, the query is not returning model data:
Project projectFound = await SpeckleAuthClient.Shared.Client.Project.GetWithModels(SpeckleProjectId);
if (projectFound == null) throw new Exception($"Speckle Project not found with id: {SpeckleProjectId}");
//Model modelFound = projectFound.models.items.FirstOrDefault(m => m.name == branchName);
var modelItems = await SpeckleAuthClient.Shared.Client.Model.GetModels(SpeckleProjectId);
Model modelFound = modelItems.items.FirstOrDefault(m => m.name == branchName);
if (modelFound == null) {
string modelDescription = "";
modelFound = await SpeckleAuthClient.Shared.Client.Model.Create(
new Speckle.Core.Api.GraphQL.Inputs.CreateModelInput(branchName, modelDescription, SpeckleProjectId));
}
This is one of those fun edge cases where legacy behavior and new workflows collide. In short:
There is no spoonmain.
Well… it exists, but not always in the way you expect!
What’s going on?
Every project starts with a main model by default — but:
It might not appear in the UI or GetModels() results.
It exists only as an ID, not a name.
If you try to create it again, the API will block you — because it’s already there (even if you can’t see it).
This happens because V2 connectors and older legacy patterns defaulted to main.
The philosophy of V3 (next-gen) connectors is: pick or define your trunk yourself.
So what should you do?
Don’t assume main exists or is discoverable.
Instead, when you create a project, create a model with a clear name (e.g., production, design, baseline) and push to that.
If you’re inheriting projects from V2-land and main appears invisible:
Look for a model with an empty name — that’s your ghost main.
TLDR:
“There is no main. Define your trunk. Create what makes sense for your workflow.”
Meantime, I implemented this try and catch behavior
if (modelFound == null) {
string modelDescription = "";
try
{
modelFound = await SpeckleAuthClient.Shared.Client.Model.Create(
new Speckle.Core.Api.GraphQL.Inputs.CreateModelInput(branchName, modelDescription, SpeckleProjectId));
}
catch (SpeckleGraphQLException ex) {
string messageError = ex.Response?.Errors?[0].Message ?? "";
if(messageError != "A branch with this name already exists" && branchName != "main") throw ex;
}
}
and looks to working around the issue. Thanks for the insights about the api behavior. I will explore querying a model with empty name or just creating a model with a name different than main.