Skip to content

apify create: workspace picker has no way to add an account #1432

Description

@l2ysho

Note

The workspace picker in apify create lists only accounts Apify already has access to, with no way out. A user whose only access came from an org install cannot target their own account, and the CLI never shows the install URL. Fix: an escape-hatch entry in the picker that opens the URL and re-reads the list, plus the same URL on the non-interactive stops.

What happened

$ apify create
✔ Name of your new Actor: test34
✔ What do you want to build? Web scraper
✔ Choose the programming language of your new Actor: JavaScript
✔ Choose a template for your new Actor. JavaScript Cheerio crawler
✔ Where will the source code live? GitHub
? Which account should own the repository?
❯ apify-projects
  apify

The Apify GitHub app was never installed on my personal account — both entries come from org installs. There is no third option, no URL, no hint. Ctrl-C is the only way out.

Why

ensureUsableIntegration returns as soon as any workspace exists, so the connect/install URL is never printed or opened:

https://github.com/apify/apify-cli/blob/master/src/lib/git-source/gitSource.ts#L331

chooseWorkspace then builds the picker from that list alone — no escape hatch:

https://github.com/apify/apify-cli/blob/master/src/lib/git-source/gitSource.ts#L413

The two grants are separate: OAuth authorization makes the integration appear, installing the app fills workspaces. The flow only offers the install URL when workspaces is empty, which is the one case this user is not in.

The URL is already in hand. GET /v2/integrations/git returns addWorkspaceUrl, and the CLI reads it at gitSource.ts:267 — it just never uses it here.

Non-interactive is blocked the same way

apify create --json --git-repo richardsolar/test34:

{ "stopReason": "unknownWorkspace",
  "error": "\"richardsolar\" is not one of your connected accounts (apify-projects, apify).",
  "gitConnectUrl": null,
  "workspaces": ["apify-projects", "apify"],
  "nextSteps": ["Re-run naming the account: --git-repo <account>/test34"] }

Circular: the next step says to name an account, and the list has no account that works. Same with no --git-repo at all — ambiguousWorkspace, gitConnectUrl: null. getGitStopUrl returns a URL only for notAuthorized and noWorkspace.

What each provider needs

Verified against apify-core src/api/src/routes/integrations/git_providers.ts:

Provider Integrations workspaces come from A missing entry means Recovery
GitHub exactly one — user.services.githubApp Apify app installations the GitHub user can see the app is not installed on that account or org addWorkspaceUrl, i.e. https://github.com/apps/<slug>/installations/new
GitLab one per connected account Namespaces.all() — every namespace that token sees no access to the group, or a different GitLab account is wanted Console integrations page
Bitbucket one per connected account /2.0/user/workspaces same as GitLab Console integrations page

So "add another GitHub account" would be wrong — only one GitHub login can ever be connected; what gets added is an app installation. GIT_PROVIDERS[provider].authorize already discriminates GitHub from the other two.

No API change needed. addWorkspaceUrl is returned whenever at least one installation exists, and the listing is live — listInstallationsForAuthenticatedUser hits GitHub per request, so re-reading after an install returns the new account.

Proposed

1. Escape hatch in the picker. Append an entry after the workspaces:

? Which account should own the repository?
❯ apify-projects
  apify
  Give Apify access to another account

Wording reuses the string already at gitSource.ts:391, so both paths read the same. The inquirer description names the mechanism per provider:

  • GitHub — Installs the Apify app on a GitHub account or organization.
  • GitLab / Bitbucket — Connects another GitLab account to Apify.

On select: print the URL, open() it, poll with the existing pollForWorkspaces, then re-show the picker with the refreshed list. On timeout, re-show the old list instead of failing.

chooseWorkspace needs provider, account and the load function, plus a loop.

2. Report the real URL in --json. Carry addWorkspaceUrl on GitSourceResult so the payload has the API's own URL rather than the hardcoded-slug fallback, and let getGitStopUrl take it as an override.

3. Give unknownWorkspace and ambiguousWorkspace a URL. Both stops get gitConnectUrl set, and the next steps gain a line matching the noWorkspace shape:

Give Apify access to the account: https://github.com/apps/apify/installations/new
then re-run apify create

Point 1 fixes the interactive dead-end; 2 and 3 fix agents and CI, where no picker can help.

Overlap

Point 3 here is point 3 of #1428. That issue is about the missing apify integrations git ls|add commands and the agent-facing surface; this one is about the interactive picker. Whichever lands first should take point 3 with it.

Related: #1428, #1425, #1424.


🤖 Generated with Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    t-buildersIssues owned by the Builders team.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions