You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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:
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.
{ "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-coresrc/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.
Note
The workspace picker in
apify createlists 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
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
ensureUsableIntegrationreturns 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
chooseWorkspacethen 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 whenworkspacesis empty, which is the one case this user is not in.The URL is already in hand.
GET /v2/integrations/gitreturnsaddWorkspaceUrl, and the CLI reads it atgitSource.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-repoat all —ambiguousWorkspace,gitConnectUrl: null.getGitStopUrlreturns a URL only fornotAuthorizedandnoWorkspace.What each provider needs
Verified against
apify-coresrc/api/src/routes/integrations/git_providers.ts:workspacescome fromuser.services.githubAppaddWorkspaceUrl, i.e.https://github.com/apps/<slug>/installations/newNamespaces.all()— every namespace that token sees/2.0/user/workspacesSo "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].authorizealready discriminates GitHub from the other two.No API change needed.
addWorkspaceUrlis returned whenever at least one installation exists, and the listing is live —listInstallationsForAuthenticatedUserhits 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:
Wording reuses the string already at
gitSource.ts:391, so both paths read the same. The inquirerdescriptionnames the mechanism per provider:Installs the Apify app on a GitHub account or organization.Connects another GitLab account to Apify.On select: print the URL,
open()it, poll with the existingpollForWorkspaces, then re-show the picker with the refreshed list. On timeout, re-show the old list instead of failing.chooseWorkspaceneedsprovider,accountand theloadfunction, plus a loop.2. Report the real URL in
--json. CarryaddWorkspaceUrlonGitSourceResultso the payload has the API's own URL rather than the hardcoded-slug fallback, and letgetGitStopUrltake it as an override.3. Give
unknownWorkspaceandambiguousWorkspacea URL. Both stops getgitConnectUrlset, and the next steps gain a line matching thenoWorkspaceshape: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|addcommands 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