Skip to content

Comments

fix: prevent client proxy from being treated as a thenable#355

Merged
darshkpatel merged 3 commits intomainfrom
fix/proxy-thenable-detection
Feb 14, 2026
Merged

fix: prevent client proxy from being treated as a thenable#355
darshkpatel merged 3 commits intomainfrom
fix/proxy-thenable-detection

Conversation

@darshkpatel
Copy link
Contributor

Why

River's client proxy uses _createRecursiveProxy which returns a callable proxy for any string property access, including .then. This causes a bug when a River client is resolved from a Promise:

// This throws "invalid river call, ensure the service and procedure you are calling exists"
const client = await spawnWorker().then(handle => handle.client);

JavaScript's Promise resolution procedure checks typeof value.then === 'function' on the resolved value. Since the proxy intercepts .then and returns a callable proxy, the runtime treats the client as a thenable and invokes .then(resolve, reject). This triggers the apply trap with path ["then"], which fails the serviceName && procName && procMethod check.

This was discovered in repl-it-web#67471 where the scribe service spawns a worker thread and returns the River client from a .then() callback.

What changed

router/client.ts: Return undefined for .then access in the recursive proxy's get trap:

get(_obj, key) {
  if (typeof key !== 'string') return undefined;
  if (key === 'then') return undefined; // prevent thenable detection
  return _createRecursiveProxy(callback, [...path, key]);
}

__tests__/typescript-stress.test.ts: Two tests confirming:

  • client.then is undefined
  • A client resolved from Promise.resolve().then(() => client) is the same object (not re-wrapped as a thenable)

Versioning

  • Breaking protocol change
  • Breaking ts/js API change

~ written by Zerg 👾

Return undefined for .then access in the recursive proxy so that
JavaScript's Promise resolution does not mistake a River client for
a thenable object.
Copy link
Member

@jackyzha0 jackyzha0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol nice

@jackyzha0
Copy link
Member

dont forget to bump the package version

@darshkpatel darshkpatel marked this pull request as ready for review February 14, 2026 07:52
@darshkpatel darshkpatel requested a review from a team as a code owner February 14, 2026 07:52
@darshkpatel darshkpatel requested review from wernst and removed request for a team February 14, 2026 07:52
@darshkpatel darshkpatel merged commit 59a9984 into main Feb 14, 2026
8 checks passed
@darshkpatel darshkpatel deleted the fix/proxy-thenable-detection branch February 14, 2026 07:53
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