Skip to content

fix: SetOrgWideDefaults._poll_action fails with stale access token after deploy#3976

Open
yippie wants to merge 1 commit into
SFDO-Tooling:mainfrom
yippie:fix/set-org-wide-defaults-stale-token
Open

fix: SetOrgWideDefaults._poll_action fails with stale access token after deploy#3976
yippie wants to merge 1 commit into
SFDO-Tooling:mainfrom
yippie:fix/set-org-wide-defaults-stale-token

Conversation

@yippie
Copy link
Copy Markdown
Contributor

@yippie yippie commented May 8, 2026

Task set_organization_wide_defaults fails 100% of the time if RTR (Refresh token rotation) is on. This is a Connected App security setting that Salesforce now requires and affects CumulusCI when embedded in MetaDeploy.

Root cause

SetOrgWideDefaults._run_task() calls _deploy(), which instantiates a new
Deploy task and invokes api() on it. Deploy.call() always calls
BaseSalesforceTask._update_credentials() → org_config.refresh_oauth_token(),
rotating org_config.access_token AFTER self.sf was already frozen in _init_task().

When _post_deploy() → _poll() → _poll_action() runs, self.sf.query() uses
the pre-deploy access token. If the org has refresh token rotation or a short
session policy, this token is invalid and every poll call returns a 401.

Sequence

Step Event org_config.access_token self.sf.session_id
SetOrgWideDefaults.call() _update_credentials() → refresh TOKEN_A
_init_task() self.sf = _init_api() TOKEN_A TOKEN_A
_deploy() → Deploy()() _update_credentials() → refresh again TOKEN_B still TOKEN_A ← stale
_post_deploy() → _poll_action() self.sf.query() TOKEN_B TOKEN_A → 401

Fix

Replace self.sf.query(...) with self.org_config.salesforce_client.query(...).

OrgConfig.salesforce_client is a @Property that constructs a fresh
simple_salesforce.Salesforce instance from self.access_token on every
access, so it always uses the current (post-deploy-refresh) token.

Tests

Updated the three _poll_action / _post_deploy tests to mock
org_config.salesforce_client via PropertyMock instead of assigning
directly to task.sf.

…ploy

The _deploy() method spawns a new Deploy task instance and calls api()
on it. Deploy.__call__() always invokes BaseSalesforceTask._update_credentials()
which calls org_config.refresh_oauth_token(), rotating the access token
stored on org_config AFTER self.sf was already frozen in _init_task().

Subsequent self.sf.query() calls in _poll_action() then use the stale
token, causing 401 failures during the sharing-enablement polling phase.

Fix: replace self.sf.query() with self.org_config.salesforce_client.query().
OrgConfig.salesforce_client is a @Property that constructs a fresh
simple_salesforce.Salesforce instance from the current org_config.access_token
on every access, so it always reflects the most recently refreshed token.

Update the three affected tests to mock org_config.salesforce_client via
PropertyMock instead of assigning to the now-unused task.sf attribute.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@yippie yippie requested a review from a team as a code owner May 8, 2026 20:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant