[source-salesloft] OAuth refresh fails in v1.5.2 due to SingleUseOauth2Authenticator attribute error
- Lenguaje dominante
- Python
- Estrellas
- 22.1k
- Forks
- 5.3k
- Métricas de merge de PR
- Métricas de PR pendientes
Descripción
### Connector Name
source-salesloft
### Connector Version
1.5.2
### What step the error happened?
Other
### Relevant information
## What step did the error happen?
During source connection check and during sync after the OAuth access token expires.
## Summary
The Salesloft Marketplace connector works while the configured OAuth access token is still valid, but fails as soon as Airbyte attempts to refresh the token.
The refresh path raises:
```text
AttributeError: 'SingleUseOauth2Authenticator' object has no attribute '_token_refresh_endpoint'
Did you mean: 'token_refresh_endpoint'?
```
This prevents long-running Salesloft syncs from continuing beyond the access-token lifetime.
## Reproduction
1. Configure `source-salesloft:1.5.2` using valid OAuth credentials:
- access token
- refresh token
- client ID
- client secret
- token expiry date
2. Set `token_expiry_date` a few minutes in the future.
3. Run `Test source` before expiry.
4. The connection succeeds.
5. Wait until `token_expiry_date` passes.
6. Run `Test source` again without changing credentials.
7. The connector fails while attempting to refresh the token.
## Observed error
```text
File ".../abstract_oauth.py", line 118, in _get_refresh_access_token_response
response = requests.request(
method="POST",
url=self.get_token_refresh_endpoint(),
data=self.build_refresh_request_body()
)
File ".../oauth.py", line 56, in get_token_refresh_endpoint
return self._token_refresh_endpoint
AttributeError:
'SingleUseOauth2Authenticator' object has no attribute
'_token_refresh_endpoint'.
Did you mean: 'token_refresh_endpoint'?
```
The exception is then surfaced as:
```text
Exception: Error while refreshing access token:
'SingleUseOauth2Authenticator' object has no attribute '_token_refresh_endpoint'
```
## Expected behavior
When the access token expires, the connector should POST the refresh token to:
```text
https://accounts.salesloft.com/oauth/token
```
and continue using the refreshed access token.
## Additional evidence
I reproduced this both:
- during a long-running sync, after substantial data had already been successfully read from Salesloft
- during a source connection test by deliberately setting `token_expiry_date` shortly in the future
This confirms that initial OAuth authentication works and that the failure occurs specifically in the refresh path.
## Possible cause
The declarative manifest uses:
```yaml
type: CustomAuthenticator
class_name: source_declarative_manifest.components.SingleUseOauth2Authenticator
token_refresh_endpoint: https://accounts.salesloft.com/oauth/token
```
but the CDK method `get_token_refresh_endpoint()` attempts to read:
```python
self._token_refresh_endpoint
```
while the authenticator appears to expose/use `token_refresh_endpoint`.
## Workaround / confirmation
I copied the connector manifest into Connector Builder and replaced the custom authenticator with Airbyte's native `OAuthAuthenticator`.
With the native authenticator, the same forced-expiry test succeeds after token expiry, including repeated `Retest saved source` checks.
This strongly suggests the Salesloft API credentials and refresh endpoint are valid and that the failure is specific to the Marketplace connector's custom authenticator implementation.
### Relevant log output
```shell
## Relevant log output
### Connection check failure after token expiry
2026-08-12 08:16:37 error Encountered an error trying to connect to stream users. Error:
File "/usr/local/lib/python3.10/site-packages/airbyte_cdk/sources/streams/http/requests_native_auth/abstract_oauth.py", line 118, in _get_refresh_access_token_response
response = requests.request(
method="POST",
url=self.get_token_refresh_endpoint(),
data=self.build_refresh_request_body()
)
File "/usr/local/lib/python3.10/site-packages/airbyte_cdk/sources/streams/http/requests_native_auth/oauth.py", line 56, in get_token_refresh_endpoint
return self._token_refresh_endpoint
AttributeError: 'SingleUseOauth2Authenticator' object has no attribute '_token_refresh_endpoint'. Did you mean: 'token_refresh_endpoint'?
The exception then propagates through the OAuth refresh path:
File "/usr/local/lib/python3.10/site-packages/airbyte_cdk/sources/streams/http/requests_native_auth/oauth.py", line 231, in get_access_token
new_access_token, access_token_expires_in, new_refresh_token = self.refresh_access_token()
File "/usr/local/lib/python3.10/site-packages/airbyte_cdk/sources/streams/http/requests_native_auth/oauth.py", line 246, in refresh_access_token
response_json = self._get_refresh_access_token_response()
File "/usr/local/lib/python3.10/site-packages/airbyte_cdk/sources/streams/http/requests_native_auth/abstract_oauth.py", line 142, in _get_refresh_access_token_response
raise Exception(f"Error while refreshing access token: {e}") from e
Exception: Error while refreshing access token: 'SingleUseOauth2Authenticator' object has no attribute '_token_refresh_endpoint'
2026-08-12 08:16:37 error Check failed
This confirms that the failure occurs specifically when the connector enters the OAuth refresh path. :contentReference[oaicite:0]{index=0} :contentReference[oaicite:1]{index=1}
### Evidence that the connector works normally before refresh is required
During the earlier sync, streams were successfully reading records before the token refresh failure occurred:
2026-08-11 16:14:15 info Read 10 records from person_stages stream
2026-08-11 16:14:15 info Finished syncing person_stages
2026-08-11 16:14:15 info Read 27 records from phone_number_assignments stream
2026-08-11 16:14:15 info Finished syncing phone_number_assignments
2026-08-11 16:14:15 info Syncing stream: steps
2026-08-11 16:14:15 info Read 0 records from steps stream
This shows that initial authentication and API requests were functioning before token refresh was triggered. :contentReference[oaicite:2]{index=2}
```
### Contribute
- [ ] Yes, I want to contribute
---
**Internal Tracking:** https://github.com/airbytehq/oncall/issues/13289
Guía de contribución
Evaluación
Este issue todavía no se ha evaluado.