cloudflare / cloudflare/terraform-provider-cloudflare

cloudflare_ai_gateway: workers_ai_billing_mode rejects "unified" and silently reverts it, but the API and OpenAPI spec both accept it

Open Beginner friendly
#7,331 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
1.3k
Forks
884
Avg merge
1d 9h
Merged PRs (30d)
5

Description

### Provider version

`cloudflare/terraform-provider-cloudflare` `main` (checked 2026-08-22), and the bridged `@pulumi/cloudflare`
6.18.0, 6.19.0 and 6.20.0-alpha. All carry the same schema.

### Affected resource

`cloudflare_ai_gateway` — the `workers_ai_billing_mode` attribute.

### Expected behaviour

`workers_ai_billing_mode` accepts `unified` as well as `postpaid`.

Cloudflare's public OpenAPI spec gives both values for the create, update and read operations on
`/accounts/{account_id}/ai-gateway/gateways`:

```json
"workers_ai_billing_mode": {
"description": "Controls how Workers AI inference calls routed through this gateway are billed. 'postpaid' bills the account directly through Workers AI; 'unified' deducts credits via AI Gateway using neuron-based pricing and delegates billing to AI Gateway.",
"type": "string",
"default": "postpaid",
"enum": ["postpaid", "unified"]
}
```

The live API agrees: a `PUT` with `"workers_ai_billing_mode": "unified"` returns 200, and the subsequent `GET`
reports `unified`. The value is also the documented way to pay for Workers AI with prepaid credits — see
https://developers.cloudflare.com/ai-gateway/configuration/manage-gateway/#configure-workers-ai-billing

### Actual behaviour

`internal/services/ai_gateway/schema.go` accepts one value, and defaults the attribute to it:

```go
"workers_ai_billing_mode": schema.StringAttribute{
Description: "Controls how Workers AI inference calls routed through this gateway are billed. Only 'postpaid' is currently supported.\nAvailable values: \"postpaid\".",
Computed: true,
Optional: true,
Validators: []validator.String{
stringvalidator.OneOfCaseInsensitive("postpaid"),
},
Default: stringdefault.StaticString("postpaid"),
},
```

This gives two failures:

1. A configuration that declares `unified` fails validation at plan time, so Unified Billing cannot be managed
as code.
2. Worse, the static default silently REVERTS a gateway. A gateway set to `unified` through the API or the
dashboard returns to `postpaid` on the next apply that sends the object, because the provider supplies the
default for the attribute the configuration leaves out. Our production and staging gateways both lost
Unified Billing this way on 2026-08-22, with no error and no plan line to warn us.

### Steps to reproduce

1. Create a `cloudflare_ai_gateway`, and leave `workers_ai_billing_mode` out of the configuration.
2. Set the gateway to Unified Billing through the dashboard or the API.
3. Change any other attribute of the resource, for example `cache_ttl`, and apply.
4. Read the gateway: `workers_ai_billing_mode` is `postpaid` again.

Adding `workers_ai_billing_mode = "unified"` to the configuration fails at step 1 instead:

```
Attribute workers_ai_billing_mode value must be one of: ["postpaid"]
```

### Note

The schema looks generated from an earlier copy of the OpenAPI spec — the description text matches the older
"Only 'postpaid' is currently supported" wording. A regeneration from the current spec should be enough.

We reach the provider through the Pulumi bridge, so there is no Terraform debug log to attach. The mismatch is
visible in the source and the spec above, and does not depend on the client.

Contributor guide

Open the contributing guide

Research direction

Start with internal/services/ai_gateway/schema.go and compare the workers_ai_billing_mode attribute with the current Cloudflare OpenAPI spec for the AI Gateway create, update, and read operations. Check how the provider schema is generated, as the issue suggests regeneration may be enough. Done means unified is accepted and a gateway left out of the configuration is not silently reverted to postpaid.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, terraform
Domain
cloud, infrastructure
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
75/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.