Summary
Two related gaps in eas integrations:posthog:connect:
- It creates a PostHog organization and project before any confirmation. The only prompt beforehand is region selection.
- There is no way to point the connection at a pre-existing PostHog project.
Together these mean a developer who already uses PostHog, and whose PostHog account email differs from their Expo account email, gets a brand-new PostHog account, organization, and project created for them — with no opportunity to say "use the project I already have," and no chance to decline before the resources exist.
To be clear about scope: the command does prompt before overwriting EXPO_PUBLIC_POSTHOG_* in .env.local and in EAS, so existing configuration is not silently replaced. The problem is confined to the provisioning step, which happens earlier and unconditionally.
Why it happens
In build/commands/integrations/posthog/connect.js (eas-cli 22.3.0), the project mutation accepts no project selector:
project = await PostHogMutation.setupPostHogProjectAsync(graphqlClient, {
appId: projectId,
posthogOrganizationConnectionId: connection.id,
})
and the lookup only finds a project EAS previously created for that app:
let project = await PostHogQuery.getPostHogProjectByAppIdAsync(graphqlClient, projectId)
There is an org-level reuse path, but it is gated on email identity:
throw new Error(`The email on the ${account.name} account already has a PostHog account,
which must be connected by approving it in a browser. ...`)
If the Expo account's email has no PostHog account, the server takes the create branch. So a developer whose PostHog login differs from their Expo login always gets new resources. Even the browser-approval branch reuses only the organization — the project is still newly created.
Managed or bare?
Bare — native directories are committed. Not relevant to the failure; the command never reaches native code.
Environment
- eas-cli 22.3.0, darwin-arm64, node 22.22.0
- Expo SDK 54, pnpm workspace monorepo
- PostHog EU Cloud
Reproducible steps to reproduce from a blank project
- Create a PostHog project manually and note that its account email differs from your Expo account email.
- Run
eas integrations:posthog:connect and select a region.
Observed:
✔ Select a PostHog region › European Union (EU)
✔ Created PostHog organization <account>-XXXXXXXX
✔ Created PostHog project <App Name>
? PostHog features to set up ›
The organization and project already exist by the time the first feature prompt appears. Aborting here (Ctrl-C) leaves them behind.
Expected behavior
Either of these would resolve it:
-
Confirm before provisioning. e.g. No PostHog account found for <email>. Create a new organization and project? (y/N). This matters more than a typical confirmation because the CLI cannot undo it: eas integrations:posthog:disconnect removes only the EAS-side link record, and the created organization must then be deleted in the PostHog UI — under an account auto-created for the Expo account's email, which the developer may not realize exists or have credentials for.
-
Allow using an existing project. A prompt to select from the connected organization's projects, and/or --posthog-project-id / --posthog-organization-id flags for the non-interactive case.
Note on the docs
https://docs.expo.dev/guides/using-posthog/ says "Re-running connect is safe: it reuses your existing organization and project." In context this means "what EAS previously created," but it reads naturally as "it will find the PostHog project I already have" — which is what led me to run the command expecting a link rather than a provision.
Summary
Two related gaps in
eas integrations:posthog:connect:Together these mean a developer who already uses PostHog, and whose PostHog account email differs from their Expo account email, gets a brand-new PostHog account, organization, and project created for them — with no opportunity to say "use the project I already have," and no chance to decline before the resources exist.
To be clear about scope: the command does prompt before overwriting
EXPO_PUBLIC_POSTHOG_*in.env.localand in EAS, so existing configuration is not silently replaced. The problem is confined to the provisioning step, which happens earlier and unconditionally.Why it happens
In
build/commands/integrations/posthog/connect.js(eas-cli 22.3.0), the project mutation accepts no project selector:and the lookup only finds a project EAS previously created for that app:
There is an org-level reuse path, but it is gated on email identity:
If the Expo account's email has no PostHog account, the server takes the create branch. So a developer whose PostHog login differs from their Expo login always gets new resources. Even the browser-approval branch reuses only the organization — the project is still newly created.
Managed or bare?
Bare — native directories are committed. Not relevant to the failure; the command never reaches native code.
Environment
Reproducible steps to reproduce from a blank project
eas integrations:posthog:connectand select a region.Observed:
The organization and project already exist by the time the first feature prompt appears. Aborting here (Ctrl-C) leaves them behind.
Expected behavior
Either of these would resolve it:
Confirm before provisioning. e.g.
No PostHog account found for <email>. Create a new organization and project? (y/N). This matters more than a typical confirmation because the CLI cannot undo it:eas integrations:posthog:disconnectremoves only the EAS-side link record, and the created organization must then be deleted in the PostHog UI — under an account auto-created for the Expo account's email, which the developer may not realize exists or have credentials for.Allow using an existing project. A prompt to select from the connected organization's projects, and/or
--posthog-project-id/--posthog-organization-idflags for the non-interactive case.Note on the docs
https://docs.expo.dev/guides/using-posthog/ says "Re-running
connectis safe: it reuses your existing organization and project." In context this means "what EAS previously created," but it reads naturally as "it will find the PostHog project I already have" — which is what led me to run the command expecting a link rather than a provision.