> ## Documentation Index
> Fetch the complete documentation index at: https://docs.speckle.systems/llms.txt
> Use this file to discover all available pages before exploring further.

# Exceptions

> SpeckleSharp error types — auth failures, transport errors, and deserialization issues

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](/developers/sdks/dotnet/getting-started/authentication#common-authentication-errors) · [Handling server capabilities](/developers/sdks/dotnet/guides/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](#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

<ResponseField name="SpeckleException" type="Exception">
  Base type for all intentional Speckle.Sdk errors. Catch this to handle any SDK-thrown failure generically.
</ResponseField>

<ResponseField name="TransportException" type="SpeckleException">
  A transport (`ServerTransport`, `SQLiteTransport`, `MemoryTransport`) failed to save or retrieve an object. Exposes the failing `Transport` instance.
</ResponseField>

<ResponseField name="SpeckleDeserializeException" type="SpeckleException">
  Deserialization of a received object graph failed — often due to a missing type registration (see the warning below) or corrupted/incompatible data.
</ResponseField>

<ResponseField name="InvalidPropNameException" type="SpeckleException">
  Thrown when setting a dynamic property on a `Base` with an invalid name (empty, `.`/`/` characters, or a double `@@` prefix).
</ResponseField>

## GraphQL Exceptions

<Warning>
  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.
</Warning>

Unwrap the `AggregateException` to inspect the underlying error, mapped from the server's GraphQL error code:

| Exception                                    | Maps to server error                                         |
| -------------------------------------------- | ------------------------------------------------------------ |
| `SpeckleGraphQLForbiddenException`           | `FORBIDDEN` / `UNAUTHENTICATED` / `UNAUTHORIZED`             |
| `SpeckleGraphQLInternalErrorException`       | `INTERNAL_SERVER_ERROR`                                      |
| `SpeckleGraphQLStreamNotFoundException`      | `STREAM_NOT_FOUND` (project not found)                       |
| `SpeckleGraphQLBadInputException`            | `BAD_USER_INPUT`                                             |
| `SpeckleGraphQLInvalidQueryException`        | `GRAPHQL_PARSE_FAILED` / `GRAPHQL_VALIDATION_FAILED`         |
| `SpeckleGraphQLWorkspaceNotEnabledException` | Workspace resources requested against a non-workspace server |
| `CannotCreateCommitException`                | Version/commit creation rejected by the server               |

`WorkspacePermissionException` is **not** in this table — see [Workspace Permission Errors](#workspace-permission-errors) below; it isn't thrown through this wrapping path.

```csharp Example lines icon="https://mintcdn.com/speckle/VtRPWzmN-ULoLfIv/images/developers/sdks/csharp.svg?fit=max&auto=format&n=VtRPWzmN-ULoLfIv&q=85&s=f2970e3b8bd4a2c7899b46211a42f251" theme={null}
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;
    }
}
```

<Note>
  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.
</Note>

## 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:

```csharp Example lines icon="https://mintcdn.com/speckle/VtRPWzmN-ULoLfIv/images/developers/sdks/csharp.svg?fit=max&auto=format&n=VtRPWzmN-ULoLfIv&q=85&s=f2970e3b8bd4a2c7899b46211a42f251" theme={null}
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.

<Note>
  `PermissionCheckResult` uses property `authorized` (US spelling) and method `EnsureAuthorised()` (UK spelling) — both match the SDK.
</Note>

## Common Failure Modes

<AccordionGroup>
  <Accordion title="SpeckleDeserializeException or objects come back as plain Base">
    The type's assembly wasn't passed to `AddSpeckleSdk`. See [Dependency injection (connectors): Registering your own types](/developers/sdks/dotnet/concepts/dependency-injection#registering-your-own-types).
  </Accordion>

  <Accordion title="SpeckleException: GraphQL response indicated that the ActiveUser could not be found">
    The account's token is invalid or expired. Re-authenticate — see [Authentication](/developers/sdks/dotnet/getting-started/authentication).
  </Accordion>

  <Accordion title="AggregateException wrapping SpeckleGraphQLWorkspaceNotEnabledException">
    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.
  </Accordion>

  <Accordion title="TransportException with no fallback remote">
    `Receive` was called with a `localTransport` that doesn't have the object, and no `remoteTransport` was provided to fall back to.
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={3}>
  <Card title="Core concepts" icon="book" href="/developers/sdks/dotnet/concepts/overview">
    Platform footguns that surface as exceptions
  </Card>

  <Card title="Handling server capabilities" icon="shield-check" href="/developers/sdks/dotnet/guides/handling-server-capabilities">
    Permission check patterns
  </Card>

  <Card title="Client API" icon="code" href="/developers/sdks/dotnet/api-reference/client">
    GraphQL calls that throw AggregateException
  </Card>
</CardGroup>
