{"record":{"id":"072166a6d6d5c84d","repo":"Stirling-Tools/Stirling-PDF","slug":"no-current-team","errorCode":null,"errorMessage":"No current team","messagePattern":"No current team","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"frontend/editor/src/cloud/contexts/SaaSTeamContext.tsx","lineNumber":199,"sourceCode":"\n  useEffect(() => {\n    if (currentTeam && !currentTeam.isPersonal) {\n      fetchTeamMembers(currentTeam.teamId);\n      // Only fetch invitations if user is team leader\n      if (currentTeam.isLeader) {\n        fetchTeamInvitations(currentTeam.teamId);\n      } else {\n        setTeamInvitations([]);\n      }\n    } else {\n      setTeamMembers([]);\n      setTeamInvitations([]);\n    }\n    setLoading(false);\n  }, [currentTeam, fetchTeamMembers, fetchTeamInvitations]);\n\n  const inviteUser = async (email: string) => {\n    if (!currentTeam) throw new Error(\"No current team\");\n\n    await apiClient.post(\"/api/v1/team/invite\", {\n      teamId: currentTeam.teamId,\n      email,\n    });\n    await fetchTeamInvitations(currentTeam.teamId);\n  };\n\n  const refreshTeams = useCallback(async () => {\n    const newCurrentTeam = await fetchMyTeams();\n    await fetchReceivedInvitations();\n    if (newCurrentTeam && !newCurrentTeam.isPersonal) {\n      await fetchTeamMembers(newCurrentTeam.teamId);\n      // Only fetch invitations if user is team leader\n      if (newCurrentTeam.isLeader) {\n        await fetchTeamInvitations(newCurrentTeam.teamId);\n      }\n    }","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/Stirling-Tools/Stirling-PDF/blob/9ef20dcab80b85041912f045e17a6aea1d08f969/frontend/editor/src/cloud/contexts/SaaSTeamContext.tsx#L181-L217","documentation":"Thrown by SaaSTeamContext.inviteUser() when currentTeam is null/undefined. The function immediately needs currentTeam.teamId to POST to /api/v1/team/invite. This fires when the team context hasn't loaded yet or the user genuinely has no current team selected.","triggerScenarios":"inviteUser() is called before the team context has resolved (race condition during initial load), or after a team was deleted/deselected. The inviteUser function is exposed via context and called from the team management UI.","commonSituations":"Team management panel rendered before fetchMyTeams() resolves; user has no teams (new account); team was just left/deleted and currentTeam was cleared; component calling inviteUser doesn't guard on currentTeam availability.","solutions":["Disable the invite button in the UI until currentTeam is non-null","Guard the inviteUser call site with a currentTeam null check before invoking","Ensure teams are loaded (loading === false) before rendering team management controls","Use isTeamLeader to gate the invite UI — only team leaders can invite"],"exampleFix":"// before\nconst inviteUser = async (email: string) => {\n  if (!currentTeam) throw new Error(\"No current team\");\n  await apiClient.post(\"/api/v1/team/invite\", { ... });\n};\n\n// after (in the UI component)\nconst handleInvite = async (email: string) => {\n  if (!currentTeam || !isTeamLeader) return;\n  await inviteUser(email);\n};","handlingStrategy":"validation","validationCode":"// Guard the invite UI before calling inviteUser\nif (!currentTeam || !isTeamLeader) {\n  return; // don't show invite controls\n}","typeGuard":null,"tryCatchPattern":"try {\n  await inviteUser(email);\n  showToast('Invitation sent', 'success');\n} catch (e) {\n  if (e instanceof Error && e.message.includes('No current team')) {\n    setError('Please select or create a team first.');\n  } else {\n    setError(e instanceof Error ? e.message : 'Failed to send invitation');\n  }\n}","preventionTips":["Disable the invite button until currentTeam is non-null and isTeamLeader is true","Ensure teams are fully loaded (loading === false) before rendering team management controls","Guard every context action that depends on currentTeam with a null check in the UI layer"],"tags":["team","invitation","validation","context","saas"],"backgroundTag":null,"analyzedSha":"9ef20dcab80b85041912f045e17a6aea1d08f969","analyzedAt":"2026-08-13T22:11:39.827Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}