Skip to content

fix(cloudflare): Fix instrumentDurableObjectWithSentry breaking Cloudflare Agents#21101

Open
JPeer264 wants to merge 4 commits into
developfrom
jp/cloudflare-agents-callable-fix
Open

fix(cloudflare): Fix instrumentDurableObjectWithSentry breaking Cloudflare Agents#21101
JPeer264 wants to merge 4 commits into
developfrom
jp/cloudflare-agents-callable-fix

Conversation

@JPeer264
Copy link
Copy Markdown
Member

By investigating #20099 it seemed that Cloudflare Agents were not working when enableRpcTracePropagation: true was set. The main reason for that was that the original target was not bound to the call.

By doing that I changed the logic a little to also make it more resistant. As the rpc trace was always everywhere attached, even though it could be that it was not directly a real RPC call. No the rpc trace is only attached when in the arguments the __sentry_rpc_meta__ is there as last parameter - which gives an extra layer of safety.

Also BUILT_IN_DO_METHODS is not needed and got removed, as we actually ignore these with the other checks (test was added for it)

The deprecated instrumentPrototypeMethods is still using the previous behavior.

This PR also proofs that we can instrument Agents on Cloudflare (cloudflare-agent e2e test)


AI text on top:

The fix binds ALL methods to the original object, ensuring private fields
work correctly. Additionally, spans are now only created when Sentry RPC
metadata (__sentry_rpc_meta__) is present in the arguments, which is only
the case for actual RPC calls that have trace propagation enabled on the
calling side. This prevents creating spans for internal framework method
calls like those made by the Agents SDK over WebSocket.

@JPeer264 JPeer264 requested a review from a team as a code owner May 21, 2026 14:35
@JPeer264 JPeer264 requested review from andreiborza and mydea and removed request for a team May 21, 2026 14:35
TestDurableObjectBase,
);

export default {
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

note: This is needed, as without it we now don't generate rpc traces. So this was fixed as well

Comment thread packages/cloudflare/src/durableobject.ts Outdated
Comment thread packages/cloudflare/src/durableobject.ts Outdated
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 21, 2026

size-limit report 📦

Path Size % Change Change
@sentry/browser 27.2 kB - -
@sentry/browser - with treeshaking flags 25.65 kB - -
@sentry/browser (incl. Tracing) 45.25 kB - -
@sentry/browser (incl. Tracing + Span Streaming) 47.47 kB - -
@sentry/browser (incl. Tracing, Profiling) 50.24 kB - -
@sentry/browser (incl. Tracing, Replay) 84.83 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 74.4 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 89.54 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 102.16 kB - -
@sentry/browser (incl. Feedback) 44.36 kB - -
@sentry/browser (incl. sendFeedback) 32.02 kB - -
@sentry/browser (incl. FeedbackAsync) 37.11 kB - -
@sentry/browser (incl. Metrics) 28.27 kB - -
@sentry/browser (incl. Logs) 28.51 kB - -
@sentry/browser (incl. Metrics & Logs) 29.22 kB - -
@sentry/react 29.03 kB - -
@sentry/react (incl. Tracing) 47.52 kB - -
@sentry/vue 32.22 kB - -
@sentry/vue (incl. Tracing) 47.16 kB - -
@sentry/svelte 27.23 kB - -
CDN Bundle 29.57 kB - -
CDN Bundle (incl. Tracing) 47.81 kB - -
CDN Bundle (incl. Logs, Metrics) 31.08 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) 49.05 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) 70.34 kB - -
CDN Bundle (incl. Tracing, Replay) 85.18 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 86.35 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) 91.05 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 92.2 kB - -
CDN Bundle - uncompressed 87.7 kB - -
CDN Bundle (incl. Tracing) - uncompressed 144.11 kB - -
CDN Bundle (incl. Logs, Metrics) - uncompressed 92.19 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 147.87 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 216.91 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 262.88 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 266.63 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 276.58 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 280.32 kB - -
@sentry/nextjs (client) 50.04 kB - -
@sentry/sveltekit (client) 45.7 kB - -
@sentry/core/server 75.94 kB - -
@sentry/core/browser 63.09 kB - -
@sentry/node-core 61.7 kB +0.01% +1 B 🔺
@sentry/node 130.4 kB - -
@sentry/node - without tracing 74.06 kB - -
@sentry/aws-serverless 86.26 kB -0.01% -1 B 🔽
@sentry/cloudflare (withSentry) - minified 171.83 kB +0.2% +342 B 🔺
@sentry/cloudflare (withSentry) 429.47 kB +0.2% +833 B 🔺

View base workflow run

@JPeer264 JPeer264 marked this pull request as draft May 22, 2026 06:23
@JPeer264 JPeer264 removed request for andreiborza and mydea May 22, 2026 06:23
@JPeer264
Copy link
Copy Markdown
Member Author

Some e2e tests are not passing, moving back to draft

@JPeer264 JPeer264 force-pushed the jp/cloudflare-agents-callable-fix branch from 7234674 to 77cce94 Compare June 1, 2026 11:09
JPeer264 added a commit that referenced this pull request Jun 1, 2026
This came up in #21101 where the link was not set in time and the tests
failed. With this PR we are waiting for the links to be actually set,
before the rootspan ends. Retrieving the stored span shouldn't take too
long - and the work was also before already executed during the
response.
@JPeer264 JPeer264 force-pushed the jp/cloudflare-agents-callable-fix branch from 77cce94 to 0b6628f Compare June 1, 2026 16:29
@JPeer264 JPeer264 marked this pull request as ready for review June 2, 2026 06:14
@JPeer264 JPeer264 force-pushed the jp/cloudflare-agents-callable-fix branch from d4dfe6d to 1dbf886 Compare June 2, 2026 06:15
Comment thread dev-packages/e2e-tests/test-applications/cloudflare-agent/tests/callable.test.ts Outdated
JPeer264 and others added 3 commits June 2, 2026 09:14
…flare Agents

The fix binds ALL methods to the original object, ensuring private fields
work correctly. Additionally, spans are now only created when Sentry RPC
metadata (`__sentry_rpc_meta__`) is present in the arguments, which is only
the case for actual RPC calls that have trace propagation enabled on the
calling side. This prevents creating spans for internal framework method
calls like those made by the Agents SDK over WebSocket.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@JPeer264 JPeer264 force-pushed the jp/cloudflare-agents-callable-fix branch from 1dbf886 to 19ffe51 Compare June 2, 2026 07:18
Comment thread packages/cloudflare/src/durableobject.ts
@JPeer264 JPeer264 requested review from a team and nicohrubec and removed request for a team June 2, 2026 07:54
@JPeer264 JPeer264 requested review from andreiborza, mydea and s1gr1d and removed request for a team and mydea June 2, 2026 07:54
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 2d80f42. Configure here.

// the original object. Bound functions ignore the thisArg passed via Reflect.apply.
const boundValue = (value as UncheckedMethod).bind(proxyTarget);
return boundMethod;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bound constructor breaks identity checks via proxy

Low Severity

The removed BUILT_IN_DO_METHODS set explicitly included 'constructor' and returned its value unmodified. Now, constructor is caught by the prop in Object.prototype check and returned as a bound function via .bind(proxyTarget). This means proxy.constructor === OriginalClass is now false, breaking any identity or type-checking code that relies on the constructor property. Unlike other former BUILT_IN_DO_METHODS members (fetch, alarm, etc.) which are now own properties and caught by the hasOwnProperty check, constructor lives solely on the prototype and falls through only to the Object.prototype check.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 2d80f42. Configure here.

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.

1 participant