How I Fix Flagsmith's Issue #7511
Issue Link: #7511
Sentry Issue: FLAGSMITH-FRONTEND-4N3 TypeError: Cannot read properties of null (reading 'environments') at store.getEnvironmentIdFromKey (./common/stores/project-store.js:179:34) at eMr (./web/components/CompareIdentities.tsx:63:17) ... (6 additional frame(s) were not displayed) When reading getEnvironmentIdFromKey from store, which is called in file CompareIdentities, the value is null/undefined.
Upon reading the error message, I ask myself, what variable is called in file CompareIdentities.tsx?
const envId = ProjectStore.getEnvironmentIdFromKey(_environmentId)
I then asked, What is _environmentId? Where does it come from? Let's see getEnvironmentIdFromKey.
getEnvironment: (api_key) =>
store.model && find(store.model.environments, { api_key }),
It's calling environments inside model variable. When does the store.model variable is null?
A model is typically null when the project data hasn't loaded yet from the API.
So my analysis question for CompareIdentities.tsx:
is there a loading state check before line 63?
What triggers the components to render - could it render before the project store has finished loading?
To answer number 2, I try to observe CompareIdentities component; how do ProjectStore is called?
const CompareIdentities: FC<CompareIdentitiesType> = ({
environmentId: _environmentId,
projectId,
}) => {
const [leftId, setLeftId] = useState<IdentitySelectType['value']>()
const [rightId, setRightId] = useState<IdentitySelectType['value']>()
const envId = ProjectStore.getEnvironmentIdFromKey(_environmentId)
const { data: projectFlags, refetch } = useGetProjectFlagsQuery(
{
environment: envId,
project: projectId,
},
{ skip: !envId || !projectId },
)
Based on the code above, ProjectStore is called inside a render function, meaning it runs on every render, including the very first render before ProjectStore.model is loaded.
Final summary: when CompareIdentities component is rendered for the first time, it calls ProjectStore.getEnvironmentIdFromKey() -> it tries to read store.model -> store.model is still null (API hasnt responded yet) -> crash
So to solve this issue, I add guard to prevent access if store.model is null:
if (store.model) {
const env = find(store.model.environments, { api_key })
return env && env.id
}
You can see my Pull Request #7778 is finally merged. Thanks a lot for Flagsmith's response. Alhamdulillah.

