Skip to content

fix(sidecar): preserve Redacted values across RPC serialization#356

Open
schutzelaars wants to merge 1 commit into
alchemy-run:mainfrom
schutzelaars:fix/rpc-redacted-prewalk
Open

fix(sidecar): preserve Redacted values across RPC serialization#356
schutzelaars wants to merge 1 commit into
alchemy-run:mainfrom
schutzelaars:fix/rpc-redacted-prewalk

Conversation

@schutzelaars
Copy link
Copy Markdown

Ran into this while testing the Vite + Cloudflare Worker setup from #331 (feat(cloudflare): vite dev). On alchemy dev, Redacted values sent through the sidecar RPC arrive on the worker side as the literal string "<redacted>".

Anything passing a Redacted through a binding hits this. In my case, Hyperdrive's password:

Cloudflare.Hyperdrive("db", {
  origin: { ..., password: secret /* Redacted<string> */ },
});

password authentication failed.

JSON.stringify calls toJSON() before the replacer, and Redacted.toJSON() returns "<redacted>", so this replacer in Sidecar/RpcHandler.ts never fires:

JSON.stringify(args, (_, value) => {
  if (Redacted.isRedacted(value)) {
    return { _tag: "Redacted", value: Redacted.value(value) };
  }
  return value;
});

Deserialize side already handles the { _tag: "Redacted", value } envelope.

Fix

Pre-walk the args with encodeRedacted before JSON.stringify:

  • recurses into arrays, plain objects, and the inner value of nested Redacted
  • skips objects with their own toJSON (Date, URL, …) so JSON.stringify keeps using their custom shape

Covered by packages/alchemy/test/Sidecar/RpcHandler.test.ts: top-level Redacted, Redacted nested in an object, and a Date arg (exercises the toJSON skip).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants