{"record":{"id":"cc5fa43e3d4e2887","repo":"hoppscotch/hoppscotch","slug":"team-collection-updated-error-json-stringify-re","errorCode":null,"errorMessage":"Team Collection Updated Error: ${JSON.stringify(result.left)}","messagePattern":"Team Collection Updated Error: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/hoppscotch-common/src/services/team-collection.service.ts","lineNumber":736,"sourceCode":"          requests: null,\n          title: result.right.teamCollectionAdded.title,\n          data: result.right.teamCollectionAdded.data ?? null,\n        },\n        result.right.teamCollectionAdded.parent?.id ?? null\n      )\n    })\n\n    const [teamCollUpdated$, teamCollUpdatedSub] = runGQLSubscription({\n      query: TeamCollectionUpdatedDocument,\n      variables: {\n        teamID: this.teamID,\n      },\n    })\n\n    this.teamCollectionUpdatedSub = teamCollUpdatedSub\n    this.teamCollectionUpdated$ = teamCollUpdated$.subscribe((result: any) => {\n      if (E.isLeft(result))\n        throw new Error(\n          `Team Collection Updated Error: ${JSON.stringify(result.left)}`\n        )\n\n      this.updateCollection({\n        id: result.right.teamCollectionUpdated.id,\n        title: result.right.teamCollectionUpdated.title,\n        data: result.right.teamCollectionUpdated.data,\n      })\n\n      this.loadingCollections.value = this.loadingCollections.value.filter(\n        (x) => x !== result.right.teamCollectionUpdated.id\n      )\n    })\n\n    const [teamCollRemoved$, teamCollRemovedSub] = runGQLSubscription({\n      query: TeamCollectionRemovedDocument,\n      variables: {\n        teamID: this.teamID,","sourceCodeStart":718,"sourceCodeEnd":754,"githubUrl":"https://github.com/hoppscotch/hoppscotch/blob/1acb8a3a7581e4db32ba0d529170c4669a2e1053/packages/hoppscotch-common/src/services/team-collection.service.ts#L718-L754","documentation":"Thrown inside the TeamCollectionUpdated GraphQL subscription callback in registerSubscriptions() when the subscription delivers a Left result. This callback handles real-time collection-title/data updates and clears the loadingCollections flag for the updated collection. Throwing in the next-handler risks crashing the RxJS chain and leaves loadingCollections stuck.","triggerScenarios":"The TeamCollectionUpdated subscription emits an error — WebSocket drop, backend GraphQL error, expired auth, or invalid teamID. The error leaves the loadingCollections entry for the in-flight collection uncleared.","commonSituations":"Auth token expired mid-subscription; network interruption; backend restart; team access revoked while subscribed; concurrent update event arriving in a format the client doesn't expect.","solutions":["Move the error path to a dedicated subscribe error handler instead of throwing in next.","Ensure loadingCollections is cleared in the error path to avoid a stuck loading spinner.","Re-register subscriptions on transient errors; re-authenticate on auth errors.","Log result.left for backend error diagnosis."],"exampleFix":"// before\nthis.teamCollectionUpdated$ = teamCollUpdated$.subscribe((result: any) => {\n  if (E.isLeft(result))\n    throw new Error(`Team Collection Updated Error: ${JSON.stringify(result.left)}`)\n  this.updateCollection(...)\n  this.loadingCollections.value = this.loadingCollections.value.filter(...)\n})\n\n// after\nthis.teamCollectionUpdated$ = teamCollUpdated$.subscribe({\n  next: (result: any) => {\n    if (E.isLeft(result)) {\n      console.error('TeamCollectionUpdated error:', result.left)\n      return\n    }\n    this.updateCollection(...)\n    this.loadingCollections.value = this.loadingCollections.value.filter(...)\n  },\n  error: (err) => { console.error('TeamCollectionUpdated stream error:', err) },\n})","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"this.teamCollectionUpdated$ = teamCollUpdated$.subscribe({\n  next: (result: any) => {\n    if (E.isLeft(result)) {\n      console.error('TeamCollectionUpdated error:', result.left)\n      // Clear loadingCollections to avoid stuck spinner\n      return\n    }\n    this.updateCollection(...)\n  },\n  error: (err) => { console.error('TeamCollectionUpdated stream error:', err) },\n})","preventionTips":["Never throw inside a .subscribe next-handler.","Ensure loadingCollections is cleared in the error path to prevent stuck spinners.","Use { next, error } subscribe signature for error handling.","Reconnect subscriptions on transient errors; re-authenticate on auth errors.","Unsubscribe all team subscriptions on team switch or logout."],"tags":["team-collections","graphql","subscription","websocket","reactive"],"backgroundTag":null,"analyzedSha":"1acb8a3a7581e4db32ba0d529170c4669a2e1053","analyzedAt":"2026-08-12T11:34:52.648Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}