cloudflare / cloudflare/claude-managed-agents

wrangler.jsonc ships maintainer's real KV/D1 IDs — fresh clones fail `npm run deploy` with error 10041

Open Beginner friendly
#42 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
274
Forks
42
PR merge metrics
No merged PRs in 30d

Description

## Summary

Commit 8042463 ("Leaning into architecture changes to fix hanging bugs", 2026-05-22) committed real, account-specific resource IDs into `wrangler.jsonc`, replacing the intentional `"id": ""` placeholders. Because the `scripts/ensure-kv.mjs` / `scripts/ensure-d1.mjs` provisioning scripts treat any non-empty ID as "already provisioned", fresh clones skip provisioning entirely and `npm run deploy` fails at Worker upload with error 10041.

## What happened

https://github.com/cloudflare/claude-managed-agents/commit/8042463c248388ae07f57a62da612427d072acc4 changed `wrangler.jsonc`:

```diff
"kv_namespaces": [
{
"binding": "SECRETS",
- "id": "",
+ "id": "36d8189b626e417d985f3887906f089a",
},
{
"binding": "EGRESS_POLICIES",
- "id": "",
+ "id": "65f3f44ccbca4f08bc87f02055ae29b1",
},
],
...
"binding": "DB",
"database_name": "claude-managed-agents-db",
- "database_id": "",
+ "database_id": "1f0a864c-282d-4108-abcc-9f2703d68448",
```

These look like the IDs from the author's own account, most likely patched in by the ensure scripts during a local deploy and then committed by accident. The comment directly above (currently `wrangler.jsonc` line ~52) still documents the intended behavior:

> The empty `"id": ""` placeholders are intentional. `scripts/ensure-kv.mjs` runs on `prebuild` and patches the real namespace IDs in place …

## Why deploys fail on a fresh clone

Both ensure scripts have a local fast path that exits early when IDs are already populated:

`scripts/ensure-kv.mjs`:

```js
const allPopulated = kvBindings.every(
(b) => typeof b.id === "string" && b.id.length > 0,
);
if (!isWorkersCi && allPopulated) {
console.log(
"[ensure-kv] all ids populated and not in Workers Builds, skipping API check",
);
process.exit(0);
}
```

`scripts/ensure-d1.mjs` has the same pattern for `database_id`.

On a fresh clone the committed foreign IDs are non-empty, so both scripts skip provisioning, and `wrangler deploy` then tries to bind KV namespaces / a D1 database that don't exist in the user's account. (The Workers Builds path is unaffected since `WORKERS_CI=1` forces the API check, which adopts-or-creates by name and re-patches the IDs.)

## Reproduction

1. `git clone https://github.com/cloudflare/claude-managed-agents && cd claude-managed-agents && npm install`
2. `npx wrangler login` (any account that doesn't own the committed IDs — i.e. everyone)
3. `npm run deploy`

Result:

```
[ensure-kv] all ids populated and not in Workers Builds, skipping API check
[ensure-d1] database_id populated and not in Workers Builds, skipping API check
...
✘ [ERROR] A request to the Cloudflare API (.../workers/scripts/claude-managed-agents) failed.

KV namespace '36d8189b626e417d985f3887906f089a' not found [code: 10041]
```

## Fix

Blank the three IDs in `wrangler.jsonc` to restore the documented placeholder behavior:

```jsonc
"id": "", // SECRETS
"id": "", // EGRESS_POLICIES
"database_id": "", // DB
```

Verified locally (2026-07-04): with the IDs blanked, a fresh `npm run deploy` provisions both KV namespaces and the D1 database and deploys cleanly.

## Suggested hardening

The fast path trusts any non-empty string, which is exactly how this slipped through. Two cheap improvements:

1. In `ensure-kv.mjs` / `ensure-d1.mjs`, verify the configured ID actually exists in the target account (one list call) before skipping — if it doesn't, fall through to adopt-or-create instead of exiting 0.
2. Optionally add a CI check or `.gitattributes`/pre-commit guard that rejects commits where these fields are non-empty, since local deploys rewrite `wrangler.jsonc` in place and make this an easy mistake to repeat.

Also worth noting: the committed values disclose real resource IDs from the maintainer's account. They aren't credentials, but you may want to rotate/remove those resources anyway.

Happy to send a PR for the one-line fix and/or the ensure-script hardening if useful.

Contributor guide

Open the contributing guide

Research direction

Start with wrangler.jsonc and confirm the three KV and D1 identifiers are the intentional empty placeholders described in its nearby comment. Read scripts/ensure-kv.mjs and scripts/ensure-d1.mjs to understand the provisioning path, then run the documented fresh-clone deployment reproduction. Done means npm run deploy provisions the resources and completes without error 10041.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
cloud, devops, infrastructure
Issue type
Bug
Difficulty
1/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.