# Migrate Mocha from 16.6 to 16.7 - Mocha

> Migration guide for Mocha v16.6 to v16.7: publish through the Postgres outbox with an open transaction or opt out of the transaction requirement.

Canonical source: https://chillicream.com/docs/mocha/migration/migrate-from-16-6-to-16-7

Update every `Mocha.*` package in the application to version 16.7 before applying these changes.

## Behavioral breaking changes

### The Postgres outbox requires a transaction

`PublishAsync` and `SendAsync` through the outbox registered with `UsePostgresOutbox()` now require an open database transaction on the DbContext or an ambient `TransactionScope`. Without one, they throw an `InvalidOperationException` and no message is written. In 16.6, such a message was inserted into the outbox table immediately, outside any later `SaveChangesAsync`, so it was dispatched even when the entity changes were never saved.

Replies, faults, requests, and scheduled messages are not affected.

The code paths that typically published without a transaction in 16.6 need one of these changes:

- **Consumers** get a transaction from `UseTransaction()`:
Diff
```
 builder.Services
     .AddMessageBus()
     .AddEntityFramework<AppDbContext>(p =>
     {
         p.UsePostgresOutbox();
+        p.UseTransaction();
     })
     .AddRabbitMQ();
```
- **Mediator handlers** get a transaction from `UseEntityFrameworkTransactions<TContext>()`:
Diff
```
 builder.Services
     .AddMediator()
+    .UseEntityFrameworkTransactions<AppDbContext>();
```
- **Other code**, such as API endpoints and background services, opens a transaction on the DbContext:
Diff
```
+await using var transaction = await db.Database.BeginTransactionAsync(cancellationToken);
+
 db.Orders.Add(order);
 await bus.PublishAsync(new OrderPlaced(order.Id), cancellationToken);
 await db.SaveChangesAsync(cancellationToken);
+
+await transaction.CommitAsync(cancellationToken);
```

Direct bus publishes use the first DbContext registered with `UsePostgresOutbox()`. A transaction on a different DbContext does not satisfy the requirement.

To keep the 16.6 behavior, set `RequireTransaction` to `false`:

Diff

```
 builder.Services
     .AddMessageBus()
     .AddEntityFramework<AppDbContext>(p =>
     {
-        p.UsePostgresOutbox();
+        p.UsePostgresOutbox(o => o.RequireTransaction = false);
     })
     .AddRabbitMQ();
```

With `RequireTransaction` set to `false`, a message published outside a transaction is written to the outbox table immediately. Inside a transaction, it is written as part of that transaction.

See [Reliability](https://chillicream.com/docs/mocha/reliability#transaction-requirements) for details.

[Edit this page on GitHub](https://github.com/ChilliCream/graphql-platform/edit/main/website/content/docs/mocha/migration/migrate-from-16-6-to-16-7.md)

Maintained by ChilliCream. Last updated on **October 19, 2026** by **Tobias Tengler**
