Azure / Azure/data-api-builder
[Bug]: 2.0 rejects filter-variable queries with HC0047; Hot Chocolate cost limits are not configurable
- Langage dominant
- C#
- Étoiles
- 1.5k
- Forks
- 370
- Merge moyen
- 3 j 22 h
- PR mergées (30 j)
- 9
Description
# [Bug]: 2.0 GA rejects `filter: $variable` queries with HC0047 — cost limits are not configurable
## What happened?
After upgrading from 1.7.93 to 2.0.8, every query that passes a whole filter input as a GraphQL variable fails with:
```json
{
"errors": [{
"message": "The maximum allowed field cost was exceeded.",
"extensions": { "code": "HC0047", "fieldCost": 1325, "maxFieldCost": 1000 }
}]
}
```
Hot Chocolate 16 (bundled since 2.0) enables static cost analysis by default with `MaxFieldCost = 1000`, and DAB exposes **no configuration** for it — `runtime.graphql` only has `depth-limit`; `ModifyCostOptions` is never called in `Startup.AddGraphQLService`.
## Why this breaks virtually every real client
Generated `*FilterInput` types are self-referential (`and: [XFilterInput!]`, `or: [XFilterInput!]`). When a filter is supplied as a variable, the cost analyzer prices the input type's **recursive worst case**, not the actual value. Measured against a DAB 2.0.8 instance (MSSQL, 131 entities) using `GraphQL-Cost: validate`:
| query shape | fieldCost |
|---|---|
| `organizations(first: 20) { items { id } }` | 30 |
| same + inline literal filter `{status: {name: {in: [$name]}}}` | 33 |
| same + `filter: $f` variable (**no value even supplied**) | **1243** |
The ~1200 floor is entity-independent — a 3-column lookup table's filter variable prices at ~1202 — so **every** `filter: $variable` query exceeds the 1000 default. In our app that's 79 call sites across 48 routes, i.e. every list page. `filter: $variable` is the natural pattern for dynamic filtering (and what most GraphQL client codegen produces), and it worked on 1.x.
Related upstream: ChilliCream/graphql-platform#9548 (cost assumes two levels of recursion for circular references).
## Expected
Either (preferably both):
1. `runtime.graphql` config for cost analysis — e.g. `cost: { enforce: bool, max-field-cost: int, max-type-cost: int }` — mirroring the existing `depth-limit` knob.
2. Defaults that don't reject variable-supplied filters on every entity (e.g. enforcement off unless configured, or variable inputs priced by provided value rather than recursive worst case).
## Steps to reproduce
1. `dab init` against any MSSQL database, add any table entity, start DAB 2.0.8.
2. `POST /graphql` with `query Q($f: FilterInput) { (filter: $f) { items { __typename } } }` and any (or no) variable value.
3. Observe HC0047 with fieldCost ≈ 1200+ vs maxFieldCost 1000.
## Version
2.0.8 (the v2.0.9 tag contains no cost-related changes, so it is equally affected)
## What database are you using?
Azure SQL / SQL Server
## What hosting model are you using?
Container (App Service)
Guide de contribution
Ouvrir le guide de contribution
Piste de recherche
Commencez dans Startup.AddGraphQLService, où ModifyCostOptions ne serait pas appelé, et examinez la gestion de runtime.graphql pour le paramètre depth-limit existant. Reproduisez le problème en envoyant via POST une requête avec une variable de filtre à /graphql après dab init, puis vérifiez que le comportement du coût est configurable et que les filtres valides fournis par variable n’échouent plus de manière inattendue avec HC0047.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- csharp, graphql
- Domaine
- api, backend
- Type d'issue
- Bug
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- Calme
- Clarté
- Plutôt claire
- Accessibilité débutants
- 48/100