#7997 Wrangler doesn't respect Unicode Separator Character in URL
Valid bug affecting KV keys with special characters (^, ...). Related to #7669. Wrangler encodes correctly but Cloudflare API may not handle encoded chars properly. Maintainer acknowledged API-side issue on related ticket.
Link to #7669, request more details from reporter (dashboard access, Workers API access, full error). Consider API-side investigation.
Analysis Report
Issue Review: cloudflare/workers-sdk#7997
Summary
KV keys containing special characters like ^ (caret) return 404 when using wrangler kv key get command.
Review Findings
Step 1 - Issue Details
| Field | Value |
|---|---|
| Created | 2025-01-31 |
| Last Updated | 2025-10-30 |
| Reporter Version | wrangler 3.107.2 |
| Current Version | wrangler 4.60.0 |
| Component | KV (wrangler) |
| Labels | bug |
| Comments | None |
Issue Description:
The reporter experiences 404 errors when trying to get KV keys with special characters in the name, specifically keys formatted like email^_email@example.com^_password. The command used was:
npx wrangler kv key get --namespace-id=<namespace_id> email\^_email@example.com\^_password
Step 2 - Issue Validity
- Issue body contains description but lacks minimal reproduction
- No error logs provided
- Operating system is WSL Ubuntu
- Issue has not been addressed by maintainers or reporter
Step 3 - Label Analysis
- Only has
buglabel - No status labels like
awaiting reporter responseorfixed - Issue remains open with no maintainer interaction
Step 4 - Related Fixes
No direct fixes found for issue #7997.
Related historical PR:
- PR #987 (merged 2022-05-13): "fix: encode key when calling
kv:ket get, don't encode when deleting a namespace"- This PR added
encodeURIComponent()to KV key operations but was before the reported issue
- This PR added
Related open issue:
- Issue #7669: "KV key delete fails with 403 when key ends with
..."- Similar problem with special characters in KV keys
- A maintainer (edmundhung) commented on 2025-01-13: "This might be an issue on the API side"
- Both issues suggest an underlying Cloudflare API limitation with certain URL-encoded characters
Step 5 - Changelog Check
- No mention of issue #7997 in wrangler CHANGELOG.md
- No recent fixes related to KV key encoding or special characters
Step 6 - Version Gap
- Reported version: 3.107.2
- Current version: 4.60.0
- Major version upgrade has occurred since the report
- However, code review shows no changes to the encoding logic in
getKVKeyValue()which still usesencodeURIComponent(key)
Step 7 - Reproduction Attempt
Not performed. Based on code review and related issue #7669:
Root cause analysis from code:
kvKeyGetCommandin/packages/wrangler/src/kv/index.tsreceives the key from CLI args- Calls
getKVKeyValue(config, accountId, namespaceId, key)in/packages/wrangler/src/kv/helpers.ts getKVKeyValuecallsfetchKVGetValue(complianceConfig, accountId, namespaceId, encodeURIComponent(key))- The key IS being URL-encoded with
encodeURIComponent() - The
^character correctly encodes to%5E
The evidence from issue #7669 suggests this is a Cloudflare API-side issue where certain URL-encoded characters are not handled properly, resulting in 403 or 404 errors.
Recommendation
Status: KEEP OPEN
Reasoning
- The issue is valid and represents a real bug affecting users with special characters in KV keys
- Related issue #7669 confirms this is a broader problem affecting multiple character types (
...and^) - A Cloudflare maintainer acknowledged the related issue may be "an issue on the API side"
- No fix has been merged for either issue
- The encoding logic in wrangler appears correct - the root cause is likely in the Cloudflare KV API
Suggested Action
- Link this issue to #7669 as they share the same root cause (API handling of URL-encoded characters)
- Consider consolidating these issues or marking one as duplicate
- This requires investigation/fix on the Cloudflare API side, not wrangler
- Request more details from reporter:
- Does the key exist and work via the dashboard?
- Can they create/read this key via the Workers KV API directly?
- What is the exact error message (404 response body)?
Suggested Comment
Thank you for reporting this issue. This appears to be related to #7669 where certain special characters in KV keys cause failures when using wrangler CLI commands.
Based on our investigation, wrangler correctly URL-encodes the key using
encodeURIComponent()(where^becomes%5E), but the Cloudflare KV API may not be handling these encoded characters correctly.A few questions to help us investigate further:
- Can you confirm this key exists and is readable via the Cloudflare Dashboard?
- Does the same key work when accessed from within a Worker using the KV bindings API?
- Could you share the full error response (not just the 404 status)?
We're tracking this as a potential API-side issue. In the meantime, consider using keys that avoid special characters like
^,..., or other URL-sensitive characters if possible.
Solution Recommendation
Root Cause Analysis
The issue is in how wrangler communicates with the Cloudflare KV API. While encodeURIComponent() correctly encodes special characters, the API doesn't know the key is URL-encoded unless told via the urlencoded=true query parameter.
Affected Code:
packages/wrangler/src/cfetch/internal.ts:272-294-fetchKVGetValue():
const resource = `${getCloudflareApiBaseUrl(complianceConfig)}/accounts/${accountId}/storage/kv/namespaces/${namespaceId}/values/${key}`;
// Missing: ?urlencoded=true
packages/wrangler/src/kv/helpers.ts:224-256-putKVKeyValue(): Same issuepackages/wrangler/src/kv/helpers.ts:272-285-deleteKVKeyValue(): Same issue
Evidence: The secret delete command in packages/wrangler/src/secret/index.ts:331-338 correctly uses url_encoded: "true" query parameter.
Proposed Solution
Add urlencoded=true query parameter to all KV API calls:
// In fetchKVGetValue:
const queryParams = new URLSearchParams({ urlencoded: "true" });
const resource = `${getCloudflareApiBaseUrl(complianceConfig)}/accounts/${accountId}/storage/kv/namespaces/${namespaceId}/values/${key}?${queryParams.toString()}`;
// In putKVKeyValue:
let searchParams = new URLSearchParams();
searchParams.set("urlencoded", "true"); // Add this line
// ... rest of existing code
// In deleteKVKeyValue:
return await fetchResult(
complianceConfig,
`/accounts/${accountId}/storage/kv/namespaces/${namespaceId}/values/${encodeURIComponent(key)}`,
{ method: "DELETE" },
new URLSearchParams({ urlencoded: "true" }) // Add this
);
Implementation Difficulty: Easy
| Factor | Assessment |
|---|---|
| Lines of code | ~5-10 lines across 3 functions |
| Risk | Low - urlencoded=true is backward compatible |
| Testing | Easy - existing test infrastructure |
| Scope | 2 files (internal.ts, helpers.ts) |
| Pattern exists | Yes - secret delete already does this correctly |
Files to Modify
packages/wrangler/src/cfetch/internal.ts- Add query param tofetchKVGetValuepackages/wrangler/src/kv/helpers.ts- Add query param toputKVKeyValueanddeleteKVKeyValuepackages/wrangler/src/__tests__/kv/key.test.ts- Add tests for Unicode/special characters
Testing Recommendations
- Add unit tests for keys with Unicode control characters (
\u001f) - Add tests for keys with URL-sensitive characters (
^,...,?,&) - Verify mock requests include
urlencoded=trueparameter - E2E test: create/get/delete keys with special characters