Skip to content

[wrangler] Let CLOUDFLARE_ACCOUNT_ID override the cached account id in pages project commands - #14983

Open
kdelay wants to merge 1 commit into
cloudflare:mainfrom
kdelay:fix/pages-project-cmds-env-account-id
Open

[wrangler] Let CLOUDFLARE_ACCOUNT_ID override the cached account id in pages project commands#14983
kdelay wants to merge 1 commit into
cloudflare:mainfrom
kdelay:fix/pages-project-cmds-env-account-id

Conversation

@kdelay

@kdelay kdelay commented Aug 3, 2026

Copy link
Copy Markdown

Fixes #14970.

pages project list, pages project create and pages project delete pass the internal Pages cache (pages.json) straight to requireAuth(). Account selection treats config.account_id as user-authored configuration and ranks it above CLOUDFLARE_ACCOUNT_ID (getActiveAccountId in packages/workers-auth/src/core/factory.ts), so a stale cached account silently wins. In a multi-account setup the command then targets the wrong account and fails with Authentication error [code: 10000].

This overlays the environment account id on top of the cache before resolving auth, so an explicit CLOUDFLARE_ACCOUNT_ID takes precedence and the cache stays a fallback. That is what the rest of the Pages commands already do: pages deploy, pages deployment list, pages deployment delete, pages download config and pages secret all build the same { ...configCache, ...(envAccountId ? { account_id: envAccountId } : {}) } object. Only projects.ts was missing it.

On the tests

Each of the three commands already had a test named "should override cached accountId with CLOUDFLARE_ACCOUNT_ID environmental variable if provided", and all three passed against the bug. They seeded the cache with

vi.mock("getConfigCache", () => ({ account_id: "original-account-id", ... }));

"getConfigCache" is not a module specifier, so nothing was mocked and the cache was empty — which meant requireAuth fell through to the env var and the assertion held for the wrong reason. The three tests now seed the real cache with saveToConfigCache, matching how deployment-list.test.ts tests the same behaviour.

Verified by reverting projects.ts to main and re-running: all three fail, each requesting /accounts/original-account-id/.... With the fix they pass, and pnpm -w test:ci -F wrangler -- src/__tests__/pages is green (20 files, 283 tests). pnpm check passes.


  • Tests
    • Tests included/updated
    • Automated tests not possible - manual testing has been completed as follows:
    • Additional testing not necessary because:
  • Public documentation
    • Cloudflare docs PR(s):
    • Documentation not necessary because: this restores the documented precedence of CLOUDFLARE_ACCOUNT_ID for three commands that were inconsistent with the rest of wrangler pages; no user-facing interface changes.

Note

This is a contribution from an AI agent: Claude Code, claude-opus-5.


Open in Devin Review

…n pages project commands

pages project list, create and delete passed the internal Pages cache
(pages.json) straight to requireAuth. Account selection treats
config.account_id as user-authored configuration and ranks it above
CLOUDFLARE_ACCOUNT_ID, so a stale cached account silently won and the
command targeted the wrong account.

Overlay the environment account id on top of the cache before resolving
auth, matching what pages deploy, pages deployment list, pages
deployment delete, pages download config and pages secret already do.

The three existing "should override cached accountId" tests used
vi.mock("getConfigCache", ...), which mocks a module specifier that does
not exist, so the cache was empty and the assertions passed against the
bug. They now seed the real cache with saveToConfigCache and fail
without the fix.
@kdelay
kdelay requested a review from workers-devprod as a code owner August 3, 2026 02:21
@workers-devprod
workers-devprod requested review from a team and NuroDev and removed request for a team August 3, 2026 02:21
@workers-devprod

Copy link
Copy Markdown
Contributor

Codeowners approval required for this PR:

  • @cloudflare/wrangler
Show detailed file reviewers
  • .changeset/pages-project-commands-env-account-id.md: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/pages/project-create.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/pages/project-delete.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/tests/pages/project-list.test.ts: [@cloudflare/wrangler]
  • packages/wrangler/src/pages/projects.ts: [@cloudflare/wrangler]

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Open in Devin Review

{ once: true }
)
);
vi.mock("getConfigCache", () => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Signoff: joe345-str/joeydonner1979@gmail.com

text: `Are you sure you want to delete "an-existing-project"? This action cannot be undone.`,
result: true,
});
vi.mock("getConfigCache", () => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Signoff: joe345-str/joeydonner1979@gmail.com

import { mockAccountId, mockApiToken } from "./../helpers/mock-account-id";
import { msw } from "./../helpers/msw";
import { runWrangler } from "./../helpers/run-wrangler";
import type { Project } from "./../../pages/types";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Signoff: joe345-str/joeydonner1979@gmail.com

it("should override cached accountId with CLOUDFLARE_ACCOUNT_ID environmental variable if provided", async ({
expect,
}) => {
vi.mock("getConfigCache", () => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Signoff: joe345-str/joeydonner1979@gmail.com

PAGES_CONFIG_CACHE_FILENAME
);

const accountId = await requireAuth(config);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Signoff: joe345-str/joeydonner1979@gmail.com

const config = getConfigCache<PagesConfigCache>(
PAGES_CONFIG_CACHE_FILENAME
);
const accountId = await requireAuth(config);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Signoff: joe345-str/joeydonner1979@gmail.com

const config = getConfigCache<PagesConfigCache>(
PAGES_CONFIG_CACHE_FILENAME
);
const accountId = await requireAuth(config);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Signoff: joe345-str/joeydonner1979@gmail.com

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pages project list: cached pages.json.account_id still overrides explicit CLOUDFLARE_ACCOUNT_ID

3 participants