# System.Text.Json.JsonException: A possible object cycle was detected. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 64. Consider using ReferenceHandler.Preserve on JsonSerializerOptions to support cycles.

- **ID:** `dotnet/serialization-cycle-detected`
- **Domain:** dotnet
- **Category:** data_error
- **Verification:** ai_generated
- **Fix Rate:** 90%

## Root Cause

The JSON serializer encountered a circular reference (e.g., a parent referencing a child that references the parent) during serialization, which it cannot handle by default in System.Text.Json.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| net6.0 | active | — | — |
| net7.0 | active | — | — |
| net8.0 | active | — | — |
| net9.0 | active | — | — |

## Workarounds

1. **Use ReferenceHandler.Preserve in JsonSerializerOptions. Example: 'var options = new JsonSerializerOptions { ReferenceHandler = ReferenceHandler.Preserve }; var json = JsonSerializer.Serialize(obj, options);' This adds $id and $ref metadata to handle cycles.** (95% success)
   ```
   Use ReferenceHandler.Preserve in JsonSerializerOptions. Example: 'var options = new JsonSerializerOptions { ReferenceHandler = ReferenceHandler.Preserve }; var json = JsonSerializer.Serialize(obj, options);' This adds $id and $ref metadata to handle cycles.
   ```
2. **Apply [JsonIgnore] on the property causing the cycle. For example, if 'Order.Customer' references 'Customer.Orders', add '[JsonIgnore]' on 'Customer.Orders' in the DTO or view model.** (90% success)
   ```
   Apply [JsonIgnore] on the property causing the cycle. For example, if 'Order.Customer' references 'Customer.Orders', add '[JsonIgnore]' on 'Customer.Orders' in the DTO or view model.
   ```
3. **Use Data Transfer Objects (DTOs) that flatten the object graph and avoid circular references. For example, create 'OrderDto' with 'CustomerId' instead of a full 'Customer' object.** (85% success)
   ```
   Use Data Transfer Objects (DTOs) that flatten the object graph and avoid circular references. For example, create 'OrderDto' with 'CustomerId' instead of a full 'Customer' object.
   ```

## Dead Ends

- **Setting MaxDepth to a very high value (e.g., 1024)** — This only increases the depth limit but does not resolve the cycle; the serializer will still throw an exception when it detects the cycle at any depth. (90% fail)
- **Using Newtonsoft.Json instead of System.Text.Json without configuring ReferenceLoopHandling** — Newtonsoft.Json also throws an error by default on cycles unless ReferenceLoopHandling.Ignore is set, so simply switching libraries does not fix the issue. (85% fail)
- **Adding [JsonIgnore] on all navigation properties randomly** — This may remove necessary data and break API contracts; a targeted approach is needed to identify the specific cycle. (75% fail)
