Workers SDK Issue Reports

← Back to Dashboard

#7997 Wrangler doesn't respect Unicode Separator Character in URL

Recommendation:KEEP OPEN
Difficulty:easy
Reasoning:

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.

Suggested Action:

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 bug label
  • No status labels like awaiting reporter response or fixed
  • 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

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 uses encodeURIComponent(key)

Step 7 - Reproduction Attempt

Not performed. Based on code review and related issue #7669:

Root cause analysis from code:

  1. kvKeyGetCommand in /packages/wrangler/src/kv/index.ts receives the key from CLI args
  2. Calls getKVKeyValue(config, accountId, namespaceId, key) in /packages/wrangler/src/kv/helpers.ts
  3. getKVKeyValue calls fetchKVGetValue(complianceConfig, accountId, namespaceId, encodeURIComponent(key))
  4. The key IS being URL-encoded with encodeURIComponent()
  5. 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

  1. The issue is valid and represents a real bug affecting users with special characters in KV keys
  2. Related issue #7669 confirms this is a broader problem affecting multiple character types (... and ^)
  3. A Cloudflare maintainer acknowledged the related issue may be "an issue on the API side"
  4. No fix has been merged for either issue
  5. The encoding logic in wrangler appears correct - the root cause is likely in the Cloudflare KV API

Suggested Action

  1. Link this issue to #7669 as they share the same root cause (API handling of URL-encoded characters)
  2. Consider consolidating these issues or marking one as duplicate
  3. This requires investigation/fix on the Cloudflare API side, not wrangler
  4. 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:

  1. Can you confirm this key exists and is readable via the Cloudflare Dashboard?
  2. Does the same key work when accessed from within a Worker using the KV bindings API?
  3. 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:

  1. packages/wrangler/src/cfetch/internal.ts:272-294 - fetchKVGetValue():
const resource = `${getCloudflareApiBaseUrl(complianceConfig)}/accounts/${accountId}/storage/kv/namespaces/${namespaceId}/values/${key}`;
// Missing: ?urlencoded=true
  1. packages/wrangler/src/kv/helpers.ts:224-256 - putKVKeyValue(): Same issue
  2. packages/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

  1. packages/wrangler/src/cfetch/internal.ts - Add query param to fetchKVGetValue
  2. packages/wrangler/src/kv/helpers.ts - Add query param to putKVKeyValue and deleteKVKeyValue
  3. packages/wrangler/src/__tests__/kv/key.test.ts - Add tests for Unicode/special characters

Testing Recommendations

  1. Add unit tests for keys with Unicode control characters (\u001f)
  2. Add tests for keys with URL-sensitive characters (^, ..., ?, &)
  3. Verify mock requests include urlencoded=true parameter
  4. E2E test: create/get/delete keys with special characters

Notes & Feedback (3)

anonymous - Jan 28, 2026, 06:44 PM
Actually the suggested fix is almost definitely incorrect, since it relies upon adding `url_encoded` param string which is not actually part of the KV REST API.
anonymous - Jan 28, 2026, 06:29 PM
Appears to be valid. Got Devin to create the PR here https://github.com/cloudflare/workers-sdk/pull/12213

Add Note