Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Cloudflare deploy fails with "binding X cannot be uploaded with pinned secrets" when Worker has a `ratelimits` binding and any secret

Open
#462 0 comments 1 reaction 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
57/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
typescript
Domain
cloud, devops

Research direction

Start in void/dist/deploy-DsW-PrRQ.mjs around bindingsFromOutput (about line 1806), where the issue says the binding type switch omits ratelimit; compare the existing cases with the suggested Workers API mapping. Then find the relevant deploy tests and add coverage for a Worker with a ratelimits binding and an existing secret using the pinned uploader. Done means that deployment succeeds and preserves the secret.

Written by the indexing model from the issue text.

Description

Versions

  • void 1.1.11, @void/deploy-cloudflare 1.1.11 (latest on npm as of 2026-10-16)
  • void deploy --platform cloudflare (direct Cloudflare target), Node 24, Workers Builds and local

Repro

  1. Project with a rate limit binding in void.config.ts:
    cloudflare: {
      ratelimits: [
        { name: "MY_RATE_LIMIT", namespace_id: "1001", simple: { limit: 30, period: 60 } },
      ],
    }
    
  2. void deploy --platform cloudflare → succeeds (Worker has no secrets yet).
  3. Set any Worker secret (void secret put FOO, or wrangler/cf workers secrets put).
  4. void deploy --platform cloudflare again → fails:
    ■ deploy: Cloudflare Worker Version upload failed (exit 1); production traffic is unchanged.
      Cloudflare binding MY_RATE_LIMIT cannot be uploaded with pinned secrets.
    
    Every subsequent deploy fails the same way while any secret exists.

Root cause

  • @void/deploy-cloudflare/dist/index.mjs (activateCloudflareVersionWithSecretsFile, ~L1354): when the active version has any secret and no candidate secrets file is passed, Void calls pinActiveSecrets and routes the upload through uploadPinnedCloudflareVersion.
  • That uploader builds bindings with bindingsFromOutput (void/dist/deploy-DsW-PrRQ.mjs ~L1806–1981), whose switch handles text, json, kv, d1, r2, durable-object, queue, ai, browser, images, hyperdrive, worker, workflow, send-email, analytics-engine-dataset, vectorize, dispatch-namespace, assets, version-metadata — but has no ratelimit case, so it hits default: throw new Error(\Cloudflare binding ${name} cannot be uploaded with pinned secrets.`)`.
  • Before the first secret, the normal wrangler versions upload --prebuilt path is used, which supports ratelimits — hence it only breaks once a secret exists.

Expected

Deploy succeeds and preserves existing secrets, as it does for other binding types.

Suggested fix

Add a ratelimit case to bindingsFromOutput mapping to the Workers API binding:

case "ratelimit":
  bindings.push({
    name,
    type: "ratelimit",
    namespace_id: requiredString(value.namespaceId ?? value.namespace_id, name),
    simple: { limit: value.simple.limit, period: value.simple.period },
  });
  break;

(plus a test: Worker with ratelimits + an existing secret deploys via the pinned uploader). It may be worth auditing the switch against all binding types Void can emit (e.g. secrets_store_secrets, mtls_certificates, worker_loaders), and failing in a pre-upload check rather than mid-deploy.

Workaround

Remove ratelimits from the config (or delete all Worker secrets) to deploy.

Dominant language
TypeScript
Stars
402
Forks
32
Avg merge
12h 1m
Merged PRs (30d)
80

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from voidzero-dev/void

All issues in voidzero-dev/void

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.