Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeError: Converting circular structure to JSON #2809

Closed
4 of 5 tasks
the21st opened this issue Aug 12, 2020 · 90 comments · Fixed by #5171
Closed
4 of 5 tasks

TypeError: Converting circular structure to JSON #2809

the21st opened this issue Aug 12, 2020 · 90 comments · Fixed by #5171

Comments

@the21st
Copy link

the21st commented Aug 12, 2020

Package + Version

  • @sentry/browser 5.19.1

Version:

5.19.1

Description

Error:

TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'b'
    |     property 'collections' -> object with constructor 'Object'
    |     property '149e8f85-8be3-4957-b38b-981c51e38da7' -> object with constructor 'Object'
 ...
  at JSON.stringify(<anonymous>)
  at eventToSentryRequest(../node_modules/@sentry/core/esm/request.js:6:20)
  at sendEvent(../node_modules/@sentry/browser/esm/transports/fetch.js:28:25)
  at sendEvent(../node_modules/@sentry/core/esm/basebackend.js:38:25)
  at call(../node_modules/@sentry/core/esm/baseclient.js:318:28)
  at _sendEvent(../node_modules/@sentry/browser/esm/client.js:45:37)
  at onfulfilled(../node_modules/@sentry/core/esm/baseclient.js:377:27)
  at onfulfilled(../node_modules/@sentry/utils/esm/syncpromise.js:136:33)
  at ? (../node_modules/@sentry/utils/esm/syncpromise.js:61:33)
  at Array.forEach(<anonymous>)
  at _executeHandlers(../node_modules/@sentry/utils/esm/syncpromise.js:55:28)
  at _attachHandler(../node_modules/@sentry/utils/esm/syncpromise.js:46:19)
  at executor(../node_modules/@sentry/utils/esm/syncpromise.js:126:19)
  at new e(../node_modules/@sentry/utils/esm/syncpromise.js:73:13)
  at then(../node_modules/@sentry/utils/esm/syncpromise.js:125:16)
  at executor(../node_modules/@sentry/core/esm/baseclient.js:348:18)
  at new e(../node_modules/@sentry/utils/esm/syncpromise.js:73:13)
  at _processEvent(../node_modules/@sentry/core/esm/baseclient.js:346:16)
  at apply(../node_modules/@sentry/core/esm/baseclient.js:91:14)
  at _invokeClient(../node_modules/@sentry/hub/esm/hub.js:58:39)
  at captureEvent(../node_modules/@sentry/hub/esm/hub.js:184:14)
  at handler(../node_modules/@sentry/browser/esm/integrations/globalhandlers.js:61:28)
  at triggerHandlers(../node_modules/@sentry/utils/esm/instrument.js:77:17)
  at Q.onerror(../node_modules/@sentry/utils/esm/instrument.js:434:9)

This is how we're reporting exceptions:

    // error: Error, severityLevel: Severity, extras: { [key: string]: any } 
    withScope(scope => {
      scope.setExtras(extras)
      scope.setLevel(severityLevel)
      captureException(error)
    })
@nicolasbadia
Copy link

nicolasbadia commented Oct 21, 2020

We have thousand of errors like this with sentry/5.26.0/bundle.min.js (and previous versions) :

Converting circular structure to JSON
    --> starting at object with constructor 'HTMLDivElement'
    |     property 'jQuery3410215558066319917922' -> object with constructor 'Object'
    |     property 'datetimepicker' -> object with constructor 'k...

and

JSON.stringify cannot serialize cyclic structures.

and

cyclic object value

Why not stringify in a try catch block?

@Nevario
Copy link

Nevario commented Jun 14, 2021

I'm also seeing this error multiple times a day and it's making it difficult to keep track of legitimate issues.

If anyone has advice on how to filter these out , that would be greatly appreciated!

@xmunoz
Copy link

xmunoz commented Jun 14, 2021

This is the only error getting reported for me whenever legitimate exceptions are triggered.

@lobsterkatie
Copy link
Member

Sorry you all are having trouble! I have a few questions:

  • Is this still happening in the latest version (which, as of now, is 6.7.1)?

  • Are any of you able to reproduce this behavior?

  • If so, what does the event look like right before this step? Do you know where in the event object this is occurring?

Also, it would be great if one of you could post a link to an example of such an error in Sentry.

We (theoretically) eliminate any cycles before we get to the jsonifying step.

@Nevario
Copy link

Nevario commented Jun 16, 2021

Hi @lobsterkatie,

Is this still happening in the latest version (which, as of now, is 6.7.1)?

Yes. I am using 6.7.1 and last received a new TypeError JSON.stringify() 2 hours ago.

Are any of you able to reproduce this behavior?

Yes, I can reproduce the error by submitting a particular form within my application... No errors are generated in the browser console.

If so, what does the event look like right before this step? Do you know where in the event object this is occurring?

Does this help?

    --> starting at object with constructor 'HTMLInputElement'
    |     property 'jQuery224046174201088114542' -> object with constructor 'Object'
    |     property 'bv.messages' -> object with constructor 'n.f...
  at JSON.stringify(<anonymous>)
  at eventToSentryRequest(../../core/src/request.ts:66:16)
  at sendEvent(../../browser/src/transports/fetch.ts:93:30)
  at sendEvent(../../core/src/basebackend.ts:94:26)
  at _sendEvent(../../core/src/baseclient.ts:449:24)
  at _sendEvent(../../browser/src/client.ts:76:11)
  at onfulfilled(../../core/src/baseclient.ts:537:14)
  at onfulfilled(../../utils/src/syncpromise.ts:102:21)
  at ? (../../utils/src/syncpromise.ts:228:19)
  at Array.forEach(<anonymous>)
  at _executeHandlers(../../utils/src/syncpromise.ts:220:20)
  at _attachHandler(../../utils/src/syncpromise.ts:208:10)
  at executor(../../utils/src/syncpromise.ts:92:12)
  at new t(../../utils/src/syncpromise.ts:34:7)
  at then(../../utils/src/syncpromise.ts:91:12)
  at _processEvent(../../core/src/baseclient.ts:527:8)
  at _captureEvent(../../core/src/baseclient.ts:459:17)
  at method(../../core/src/baseclient.ts:143:12)
  at _invokeClient(../../hub/src/hub.ts:475:23)
  at captureEvent(../../hub/src/hub.ts:250:10)
  at handler(../../browser/src/integrations/globalhandlers.ts:105:20)
  at triggerHandlers(../../utils/src/instrument.ts:101:7)
  at ft.onerror(../../utils/src/instrument.ts:608:5)
  at Object.trigger(/js/jquery-2.2.4.min.js:4:4869)
  at HTMLFormElement.<anonymous>(/js/jquery-2.2.4.min.js:4:5328)
  at Function.each(/js/jquery-2.2.4.min.js:2:2861)
  at n.fn.init.each(/js/jquery-2.2.4.min.js:2:845)
  at n.fn.init.trigger(/js/jquery-2.2.4.min.js:4:5304)
  at b._submit(/js/combined.min.js:1:305795)
  at b.validate(/js/combined.min.js:1:310007)
  at HTMLFormElement.<anonymous>(/js/combined.min.js:1:298341)
  at HTMLFormElement.dispatch(/js/jquery-2.2.4.min.js:3:7537)
  at HTMLFormElement.r.handle(/js/jquery-2.2.4.min.js:3:5620)
  at Object.trigger(/js/jquery-2.2.4.min.js:4:4818)
  at HTMLFormElement.<anonymous>(/js/jquery-2.2.4.min.js:4:5328)
  at Function.each(/js/jquery-2.2.4.min.js:2:2861)
  at n.fn.init.each(/js/jquery-2.2.4.min.js:2:845)
  at n.fn.init.trigger(/js/jquery-2.2.4.min.js:4:5304)
  at saveProject(/js/foxoms/appHelper.min.js:1:2750)
  at HTMLAnchorElement.onclick(/project/view/28858:1:1)

Also, it would be great if one of you could post a link to an example of such an error in Sentry.

Sentry Issue link

Thanks for looking into this!

Tim

@lobsterkatie
Copy link
Member

Thanks.

Yes, I saw that stacktrace in the original post, and it makes sense that that's where the problem is happening. And sorry for being unclear, but I was actually hoping that since you can reproduce it, you could stick a debugger in your code right before the crash and look at the event object and figure out where the circular reference is and post that part of the object.

@Nevario
Copy link

Nevario commented Jun 17, 2021

I don't really know anything about Sentry so I don't think I'm going to be much help with debugging this. However I can send you a screen recording and username / password to our SAAS where you can investigate further.

I'll post those details in the support ticket I opened with Sentry.

@ffxsam
Copy link

ffxsam commented Jun 20, 2021

We've been running into this error lately, and the bad part is, it supercedes the actual error we're trying to capture. So users are running into bugs in our app, and we can't get the full context.

Here's a link to such an issue (only Sentry support will be able to access it):
https://sentry.io/organizations/reelcrafter/issues/2465876224/?project=1384460&query=is%3Aunresolved

Public link for everyone else:
https://sentry.io/share/issue/4693c970ebf84ffca15a3403e18e53eb/

In our case, we're passing a Vue component's entire $data variable, which is basically all the reactive variables that belong to a component. Taking some responsibility here, I should probably use something like safe-json-stringify to stringify that myself, then JSON.parse() it before passing it to Sentry, so Sentry can format it nicely.

    Vue.prototype.$reportError = function (
      exception: any,
      options: ReportErrorOptions,
      metadata?: Record<string, any>
    ) {
      reportError(exception, options, {
        ...metadata,
        component: this.$options.name,
        componentProps: JSON.parse(safeJsonStringify(this.$props)),
        componentData: JSON.parse(safeJsonStringify(this.$data)),
      });
    }

I'll try this going forward, though ideally, Sentry should probably perform a safe stringify internally to save us the step. 🙂

@xmunoz
Copy link

xmunoz commented Jun 21, 2021

I did more debugging on why we're seeing this issue and it's related to usage of the cookies package. I believe the Cookies object in that package has some circular references.

@kamilogorek
Copy link
Contributor

I'll try this going forward, though ideally, Sentry should probably perform a safe stringify internally to save us the step. 🙂

We do that for breadcrumbs, user, extra, and contexts. Would be great to catch which field is not normalized.
@ffxsam would you be able to use beforeSend or any other mechanism to pinpoint which event field is causing a trouble here?

@ffxsam
Copy link

ffxsam commented Jun 21, 2021

@kamilogorek So, to continue showing that path from the code above:

The object in the 3rd argument above gets passed into reportError() which starts like this:

export default function reportError(
  exception: any,
  options: ReportErrorOptions,
  metadata?: Record<string, any>
) {
  let extra = metadata || {};

and then:

  Sentry.setContext('clientData', {
    ...extra,
    rawException: exception,
    while: options.while,
  });

So, indeed, it's the context that's not being safe-stringified, it looks like.

@kamilogorek
Copy link
Contributor

That is really odd, as we definitely normalize those, see: https://github.com/getsentry/sentry-javascript/blob/master/packages/core/src/baseclient.ts#L331-L393 🤔

@ffxsam
Copy link

ffxsam commented Jun 22, 2021

Though, the error is happening in a JSON.stringify call within https://github.com/getsentry/sentry-javascript/blob/master/packages/core/src/request.ts

Hmm, so maybe it's not the context.

@xmunoz
Copy link

xmunoz commented Jun 22, 2021

We're using the node SDK, here is where the issue is being triggered:
Captura de pantalla de 2021-06-22 11-04-45

@kamilogorek
Copy link
Contributor

That's an accurate assessment, however, eventToSentryRequest is never called by anything other than sendEvent, which in turn is only called by captureEvent. So there's no flow available in the SDK that'd omit this serialization, and that's why I'm kinda confused and not sure where the issue originates from.

@ffxsam
Copy link

ffxsam commented Jun 23, 2021

Let us know if there's some way we can help pinpoint the issue!

@kamilogorek
Copy link
Contributor

What I did to debug #3727 is:

  1. Get reproducible error scenario
  2. Add Sentry.addGlobalEventProcessor(event => { debugger; })
  3. Trigger error
  4. Call JSON.stringify(error) and trace the source of circular reference

Once we have the source, we'll be able to reproduce and patch it easily. The biggest problem now is actually knowing the source of that reference.

@ffxsam
Copy link

ffxsam commented Jun 25, 2021

I'll try that out next time I get some free time, unless someone beats me to it!

@ffxsam
Copy link

ffxsam commented Jun 30, 2021

I can't seem to replicate it now, but our users in production sure can. 😕

The last error was interesting, actually. The error was properly caught (it was an S3 timeout error):
https://sentry.io/share/issue/ae3a5367cac143418d35c642017dc48a/

But it also generated a separate "circular structure" issue, too. There must've been something in the S3 error that it didn't like, just not sure what. I'm fairly certain it wasn't anything I was setting in the context or extra.

@kamilogorek
Copy link
Contributor

@ffxsam there's one more thing you can try (which is basically what #3776 will provide under the hood)

import { normalize } from '@sentry/utils';

Sentry.init({
  beforeSend(event) {
    return normalize(event);
  }
});

@xmunoz
Copy link

xmunoz commented Jul 8, 2021

The above fix worked for me.

That said, I've attached the json stacktrace from Sentry. Does this help you track down the root cause?
sentry.json.log

@kamilogorek
Copy link
Contributor

Unfortunately, there's nothing that'd point to the malformed data in this JSON log.

@kamilogorek
Copy link
Contributor

If someone stumbles upon this issue, starting v6.9.0 you can use an internal option ensureNoCircularStructures that will do exactly what my snippet above does. As mentioned, it's an experiment, and internal, so whenever you update your SDK past v6.9.0, make sure that it's still available.

Sentry.init({
  _experiments: {
    ensureNoCircularStructures: true
  }
})

This should allow the malformed events to be delivered to Sentry and should allow you to see some [Circular ~] references in the data UI.

@Ben-Mack
Copy link

I've updated to 6.9.0 and set ensureNoCircularStructures: true like above guidance, but still having these errors:

Mostly:
Screenshot 2021-07-24 153048

Sometimes:

Screenshot 2021-07-24 153052

@lobsterkatie
Copy link
Member

@Ben-Mack - Can you please link to the above issues in Sentry?

@xmunoz
Copy link

xmunoz commented Jun 20, 2022

Downgrading to 7.1.1 fixed it for me.

@panzelva
Copy link

panzelva commented Jun 26, 2022

Hello, we also have this problem on 7.3.0.

event id: 14578f51f61045039d61d7de5f6830a7
project id: 5278129

by looking into stack trace, it looks like problem is somewhere around here: https://github.com/getsentry/sentry-javascript/blob/master/packages/utils/src/envelope.ts#L71

@lforst
Copy link
Member

lforst commented Jun 27, 2022

@xmunoz @panzelva would you mind pasting the whole link for the issues in question? (We also need the org-slug to be able to access them) Thanks!

@panzelva
Copy link

@lforst sure thing, here you are: https://sentry.io/organizations/schizofreny/issues/3369770918/events/ed99a33af0b14e39bfdc2287da2f43e1/?project=5278129

However as I am looking at the event, it actually stopped - no idea why.

@Ohcui
Copy link

Ohcui commented Jun 28, 2022

Issued on applying 7.2.0 to exsiting Vue projects.
All application errors reported as this, and errors in console were shadowed.
Please help

TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'xr'
    --- property '_renderProxy' closes the circle
  at JSON.stringify(<anonymous>)
  at ee(/js/chunk-vendors.fd15b155.js:185:8814)
  at l(/js/chunk-vendors.fd15b155.js:185:36159)
  at Object.i [as add](/js/chunk-vendors.fd15b155.js:185:34957)
  at Object.a [as send](/js/chunk-vendors.fd15b155.js:185:36541)
  at Ne._sendEnvelope(/js/chunk-vendors.fd15b155.js:185:17310)
  at Ne.sendEvent(/js/chunk-vendors.fd15b155.js:185:13186)
  at Ne.sendEvent(/js/chunk-vendors.fd15b155.js:185:24191)
  at ? (/js/chunk-vendors.fd15b155.js:185:16877)
  at Array.<anonymous>(/js/chunk-vendors.fd15b155.js:41:2618)
  at ? (/js/chunk-vendors.fd15b155.js:41:3332)
  at Array.forEach(<anonymous>)
  at s._executeHandlers(/js/chunk-vendors.fd15b155.js:41:3283)
  at ? (/js/chunk-vendors.fd15b155.js:41:2702)
  at new s(/js/chunk-vendors.fd15b155.js:41:2492)
  at s.then(/js/chunk-vendors.fd15b155.js:41:2565)
  at Ne._processEvent(/js/chunk-vendors.fd15b155.js:185:16659)
  at Ne._captureEvent(/js/chunk-vendors.fd15b155.js:185:15873)
  at Ne.captureEvent(/js/chunk-vendors.fd15b155.js:185:11808)
  at ? (/js/chunk-vendors.fd15b155.js:202:8896)
  at h._withClient(/js/chunk-vendors.fd15b155.js:202:10891)
  at h.captureEvent(/js/chunk-vendors.fd15b155.js:202:8874)
  at Ot(/js/chunk-vendors.fd15b155.js:185:31885)
  at ? (/js/chunk-vendors.fd15b155.js:185:30899)
  at p(/js/chunk-vendors.fd15b155.js:296:5283)
  at D.l.onunhandledrejection(/js/chunk-vendors.fd15b155.js:296:9372)

@xmunoz
Copy link

xmunoz commented Jul 4, 2022

Can we re-open this issue? This is not fixed, I can't upgrade until we get a resolution, and it appears that many people are in the same situation.

@lforst
Copy link
Member

lforst commented Jul 5, 2022

@xmunoz yeah. We need to find a way to fix this sustainably. Currently, we only normalize parts of the payload we send to Sentry and it seems like "unsafe"/circular data slips through in some places. It's a bit like playing Whac-A-Mole.

I have a solution in mind where we normalize events in one central place right before sending it to Sentry, however, this involves rethinking how data is passed to the SDK and handled within (i.e. somehow marking all data that is given to the SDK or gathered by the SDK as "unsafe").

@lforst lforst reopened this Jul 5, 2022
@ffxsam
Copy link

ffxsam commented Jul 19, 2022

This is still an issue for us, and we're using @sentry/browser 7.5.0.

Converting circular structure to JSON
    --> starting at object with constructor 'constructor'
    |     property 'response' -> object with constructor 'constructor'
    --- property 'request' closes the circle

@ffxsam
Copy link

ffxsam commented Jul 26, 2022

The thing I'm most concerned about is if this is an actual error that Sentry is attempting to log or if it's just a random Sentry error we can ignore. Hopefully not the former, which means we're missing potentially important issues.

https://sentry.io/share/issue/2e7b97a984c14c3496eada587f42efc2/

@lforst @kamilogorek @lobsterkatie Any insight into this?

@alexblack
Copy link

alexblack commented Jul 31, 2022

This is still an issue for us, using @sentry/node 7.8.0

TypeError
Converting circular structure to JSON
    --> starting at object with constructor 'Object'
    |     property 'httpAgent' -> object with constructor 'Agent'
    |     property 'sockets' -> object with constructor 'Object'
    |     ...
    |     prop...

Would it make sense to use something like https://www.npmjs.com/package/json-stable-stringify instead of JSON.stringfy?

Screen Shot 2022-07-31 at 11 00 19 AM

@lforst
Copy link
Member

lforst commented Aug 1, 2022

The thing I'm most concerned about is if this is an actual error that Sentry is attempting to log or if it's just a random Sentry error we can ignore. Hopefully not the former, which means we're missing potentially important issues.

@ffxsam Generally, when this error happens, the SDK is trying to log something. 😕

I'd currently be interested in how many people are affected by this and to what extent/event count so we can prioritize this. Nevertheless, I'm gonna bug the rest of the team about this error some more because I am a bit tired of looking at this particular issue. 😄

@ffxsam
Copy link

ffxsam commented Aug 2, 2022

If it helps at all, I'm using the Vue integration. I'll bet that it's passing part of a Vue component into Sentry and that might be causing the issue.

@alexblack
Copy link

alexblack commented Aug 11, 2022

We've seen 28 of these in the last 14 days in our nodejs project, would love a fix!

@lforst
Copy link
Member

lforst commented Aug 12, 2022

We've seen 28 of these in the last 14 days in our nodejs project, would love a fix!

@alexblack 28 different issues or a total event count of 28? Still trying to get a feeling for how pressing this is.

@alexblack
Copy link

alexblack commented Aug 12, 2022 via email

@renanbronchart
Copy link

I have this problem too but on the sdk @sentry/react-native

Look at this photo.

I have this error in local and in production.
It's very embarassing because it causes crash on my end users.

Have you found a solution for that or not yet?

Capture d’écran 2022-09-23 à 01 05 54

@alexblack
Copy link

Any chance of a fix? Would some simple defensive programming help? eg catch this much closer to the source (and report it to your own sentry, instead of ours), then continue to report the actual error to our sentry (missing whatever failed JSON.stringify causing this exception)

@xmunoz
Copy link

xmunoz commented Sep 29, 2022

I haven't been able to upgrade past 7.1.1 because of this bug.

@lforst
Copy link
Member

lforst commented Sep 29, 2022

Ok small update here: I just merged #5851 which is supposed to get rid of the circular reference error in case a circular reference error would occur. It's probably not bulletproof yet and also has a slight performance penalty - which is why this hopefully won't be a permanent solution.

We still hope this will fix the issue. It will be included in the next release of the SDK. I'll respond to this issue again once it's released to let everybody know.

@AbhiPrasad
Copy link
Member

This fix has been released with https://github.com/getsentry/sentry-javascript/releases/tag/7.14.1, please let us know if there are any issues!

@mihoward21
Copy link

I am currently seeing this issue (I think, at least it looks similar), I'm using the nextjs sdk, version 7.102.0. I'd assume that version has the fix you deployed?

Happy to provide any details if it will help. Seeing this in Sentry:

Converting circular structure to JSON
    --> starting at object with constructor 'HTMLMetaElement'
    |     property '__reactFiber$cfdnihb3i6i' -> object with constructor 'ii'
    --- property 'stateNode' closes the circle

And I only seem to get this error from mobile devices.

If there's any more information I can provide, or if you want me to open a new ticket or anything, just let me know. Thanks!

@lforst
Copy link
Member

lforst commented Mar 13, 2024

@mihoward21 This should not happen at all anymore. Are you sure this is coming from the SDK and not some other part of your application? What does the stack trace show?

@mihoward21
Copy link

@lforst I'm not sure of anything, lol. Been trying to figure this out for a while and am quite perplexed. I'm adding breadcrumbs before my own calls to Sentry's captureException so I can see if it's something I'm doing. Found one more call I had missed so I will update that next week. But I think it's just the SDK?

Here is a stack trace from chrome mobile on an android:
Screenshot 2024-03-15 at 1 58 54 PM

And here is another stack trace from mobile safari on iphone:
Screenshot 2024-03-15 at 1 59 56 PM

@mihoward21
Copy link

Could this just be an issue with a browser extension (or something similar specific to mobile devices)? That's my best guess right now

@lforst
Copy link
Member

lforst commented Mar 18, 2024

@mihoward21 So this does not look like the error is coming from inside the SDK. Otherwise we'd see Sentry SDK code as the top frame. It's most likely some other code running on your page - what exactly we cannot say. It might very well be a browser extension.

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

Successfully merging a pull request may close this issue.