Skip to main content
When authentication fails, a transport cannot reach the server, or your custom types do not deserialize, Speckle.Sdk throws typed exceptions. Handle these in production automations and connectors. Read next: Authentication · Handling server capabilities

Exception Hierarchy

Every Speckle-specific exception derives from SpeckleException (itself a plain Exception). That covers most SDK-thrown failures — but not GraphQL response errors from IClient resource calls, which the SDK always wraps in a plain AggregateException. See GraphQL Exceptions below before you write a single catch (SpeckleException) block and assume it covers everything.
Exception
├─ AggregateException                  // thrown by IClient GraphQL calls; see below
│  └─ InnerExceptions: one or more Api.SpeckleGraphQLException (or subclass) per GraphQL error
└─ SpeckleException
   ├─ InvalidPropNameException          // invalid dynamic property name on Base
   ├─ Transports.TransportException     // a transport failed to send/receive
   ├─ Serialisation.SpeckleDeserializeException
   └─ Api.SpeckleGraphQLException       // base type for GraphQL response errors (see below for how it's thrown)
      ├─ SpeckleGraphQLForbiddenException
      ├─ SpeckleGraphQLInternalErrorException
      ├─ SpeckleGraphQLStreamNotFoundException
      ├─ SpeckleGraphQLBadInputException
      ├─ SpeckleGraphQLInvalidQueryException
      ├─ SpeckleGraphQLWorkspaceNotEnabledException
      ├─ WorkspacePermissionException    // thrown directly, not via a GraphQL error code — see below
      └─ CannotCreateCommitException

Core Exceptions

SpeckleException
Exception
Base type for all intentional Speckle.Sdk errors. Catch this to handle any SDK-thrown failure generically.
TransportException
SpeckleException
A transport (ServerTransport, SQLiteTransport, MemoryTransport) failed to save or retrieve an object. Exposes the failing Transport instance.
SpeckleDeserializeException
SpeckleException
Deserialization of a received object graph failed — often due to a missing type registration (see the warning below) or corrupted/incompatible data.
InvalidPropNameException
SpeckleException
Thrown when setting a dynamic property on a Base with an invalid name (empty, .// characters, or a double @@ prefix).

GraphQL Exceptions

GraphQL response errors from IClient resource calls (client.Project, client.Model, client.Version, and so on) are not thrown directly as a SpeckleGraphQLException subtype. They’re always wrapped in a plain AggregateException, with one SpeckleGraphQLException subtype per GraphQL error in InnerExceptions. A direct catch (SpeckleGraphQLStreamNotFoundException) around a resource call will never trigger — and neither will catch (SpeckleException), since AggregateException doesn’t derive from it.
Unwrap the AggregateException to inspect the underlying error, mapped from the server’s GraphQL error code:
ExceptionMaps to server error
SpeckleGraphQLForbiddenExceptionFORBIDDEN / UNAUTHENTICATED / UNAUTHORIZED
SpeckleGraphQLInternalErrorExceptionINTERNAL_SERVER_ERROR
SpeckleGraphQLStreamNotFoundExceptionSTREAM_NOT_FOUND (project not found)
SpeckleGraphQLBadInputExceptionBAD_USER_INPUT
SpeckleGraphQLInvalidQueryExceptionGRAPHQL_PARSE_FAILED / GRAPHQL_VALIDATION_FAILED
SpeckleGraphQLWorkspaceNotEnabledExceptionWorkspace resources requested against a non-workspace server
CannotCreateCommitExceptionVersion/commit creation rejected by the server
WorkspacePermissionException is not in this table — see Workspace Permission Errors below; it isn’t thrown through this wrapping path.
https://mintcdn.com/speckle/VtRPWzmN-ULoLfIv/images/developers/sdks/csharp.svg?fit=max&auto=format&n=VtRPWzmN-ULoLfIv&q=85&s=f2970e3b8bd4a2c7899b46211a42f251Example
try
{
    var project = await client.Project.Get("invalid-id");
}
catch (AggregateException ex)
{
    switch (ex.InnerException)
    {
        case SpeckleGraphQLStreamNotFoundException:
            Console.WriteLine("Project not found.");
            break;
        case SpeckleGraphQLForbiddenException:
            Console.WriteLine("Not authorized — check the token's scopes.");
            break;
        default:
            throw;
    }
}
GraphQL calls typically produce a single error, so ex.InnerException (the first inner exception) is usually enough. If you need to handle a request that can fail with multiple simultaneous errors, iterate ex.InnerExceptions instead, or call ex.Flatten() first.

Workspace Permission Errors

WorkspacePermissionException is a SpeckleGraphQLException subclass, but it isn’t mapped from a GraphQL error code and isn’t wrapped in an AggregateException. It’s thrown directly by client-side permission checks — for example after calling a CanCreateModelIngestion-style permission check and not handling a denied result:
https://mintcdn.com/speckle/VtRPWzmN-ULoLfIv/images/developers/sdks/csharp.svg?fit=max&auto=format&n=VtRPWzmN-ULoLfIv&q=85&s=f2970e3b8bd4a2c7899b46211a42f251Example
try
{
    permissionResult.EnsureAuthorised();
}
catch (WorkspacePermissionException)
{
    Console.WriteLine("You don't have permission to perform this action in this workspace.");
}
Because it derives from SpeckleException (not AggregateException), a catch (SpeckleException) block does catch it — unlike the GraphQL error-code exceptions above.
PermissionCheckResult uses property authorized (US spelling) and method EnsureAuthorised() (UK spelling) — both match the SDK.

Common Failure Modes

The type’s assembly wasn’t passed to AddSpeckleSdk. See Dependency injection (connectors): Registering your own types.
The account’s token is invalid or expired. Re-authenticate — see Authentication.
You called a client.Workspace method against a server without workspaces enabled. Check with client.Server.IsWorkspaceEnabled() first. Remember to catch AggregateException and inspect InnerException, not SpeckleGraphQLWorkspaceNotEnabledException directly.
Receive was called with a localTransport that doesn’t have the object, and no remoteTransport was provided to fall back to.

Next Steps

Core concepts

Platform footguns that surface as exceptions

Handling server capabilities

Permission check patterns

Client API

GraphQL calls that throw AggregateException
Last modified on July 10, 2026