expo / expo/eas-cli

integrations:posthog:connect creates an org and project before any confirmation, with no way to use an existing PostHog project

Open
#4,273 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
1.4k
Forks
236
Avg merge
3d 8h
Merged PRs (30d)
98

Description

### Summary

Two related gaps in `eas integrations:posthog:connect`:

1. It creates a PostHog organization and project **before any confirmation**. The only prompt beforehand is region selection.
2. 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:

```js
project = await PostHogMutation.setupPostHogProjectAsync(graphqlClient, {
appId: projectId,
posthogOrganizationConnectionId: connection.id,
})
```

and the lookup only finds a project EAS previously created for that app:

```js
let project = await PostHogQuery.getPostHogProjectByAppIdAsync(graphqlClient, projectId)
```

There is an org-level reuse path, but it is gated on email identity:

```js
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

1. Create a PostHog project manually and note that its account email differs from your Expo account email.
2. Run `eas integrations:posthog:connect` and select a region.

Observed:

```
✔ Select a PostHog region › European Union (EU)
✔ Created PostHog organization -XXXXXXXX
✔ Created PostHog project
? 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:

1. **Confirm before provisioning.** e.g. `No PostHog account found for . 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.

2. **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.

Contributor guide

Open the contributing guide

Research direction

Start in build/commands/integrations/posthog/connect.js, then inspect PostHogMutation.setupPostHogProjectAsync and PostHogQuery.getPostHogProjectByAppIdAsync. Trace when provisioning occurs relative to the region and feature prompts. Done means the command confirms before creating resources and provides a documented path to select or specify an existing PostHog project.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
api, cli
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.