dosubot[bot] commented on issue #8847: URL: https://github.com/apache/incubator-devlake/issues/8847#issuecomment-4305998682
<!-- Greeting --> Hi @fxgagnon! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the incubator-devlake team. <!-- Answer --> Those debug logs confirm the root cause. The `"[remote_api_helper] Reused api client"` message comes from [`DsRemoteApiProxyHelper.getApiClient()`](https://github.com/apache/incubator-devlake/blob/2c15ad880dce830c6512fa58039527cbf4745b8b/backend/helpers/pluginhelper/api/ds_remote_api_proxy_api.go#L63-L93), which caches API clients in memory keyed by `connection.GetHash()` (a combination of connection ID + `UpdatedAt` timestamp). Once a client is cached, it's reused indefinitely — the GitHub App installation token baked into that client is never refreshed. The flow when the bug triggers: 1. First remote-scopes request creates an API client, fetches a fresh installation token, and caches the client. 2. After ~1 hour the token expires. 3. Subsequent requests hit the cache (`"Reused api client"`), send the expired token to GitHub, get a 401, and the response is interpreted as "no orgs/repos" — hence the empty result with a `200` status (no error surfaced). The `"Authorization is empty"` line in your logs is likely from the DevLake auth middleware checking the *incoming* HTTP request (user → DevLake), not the outgoing GitHub request — it's unrelated to the token issue itself. The same [`RemoteApiHelper.GetApiClient()`](https://github.com/apache/incubator-devlake/blob/2c15ad880dce830c6512fa58039527cbf4745b8b/backend/helpers/pluginhelper/api/remote_api_helper.go#L131-L150) in `remote_api_helper.go` has the identical caching pattern without any token expiry check. **Why collection still works:** Task-based data collection creates a fresh API client per task execution via `CreateApiClient(taskCtx, connection)`, so each pipeline run gets a new token. **Quickest fix path** if you're planning to submit a PR: make `GetHash()` return `""` for GitHub App connections (disabling caching and forcing a fresh client + token per request), or add a TTL/expiry check in `getApiClient()` so cached clients are evicted before the token's ~1 hour lifetime. The Zentao plugin already uses the empty-hash approach as a precedent for connections with expiring credentials. <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot?utm_source=github&utm_medium=bot-comment&utm_campaign=github-comment-footer-20260415&utm_content=reply-with-mention&utm_term=apache%2Fincubator-devlake).* --- Share context across your team and agents. Try [Dosu](https://dosu.dev?utm_source=github&utm_medium=bot-comment&utm_campaign=github-comment-footer-20260415&utm_content=knowledge-infrastructure-tagline&utm_term=apache%2Fincubator-devlake). [](https://app.dosu.dev/response-feedback?utm_source=github&utm_medium=bot-comment&utm_campaign=github-comment-footer-20260415&utm_content=knowledge-infrastructure-feedback&utm_term=apache%2Fincubator-devlake#message_id=1ee93181-aa43-40c4-b01a-a273427f7c32) [](https://github.dosu.com/apache/incubator-devlake?utm_source=github&utm_medium=bot-comment&utm_campaign=github-comment-footer-20260415&utm_content=knowledge-infrastructure-learn-repo&utm_term=apache%2Fincubator-devlake) [](https://app.dosu.dev/signup?referrer=openSource&source=github-footer&utm_source=github&utm_medium=bot-comment&utm_campaign=github-comment-footer-20260415&utm_content=knowledge-infrastructure-add-team&utm_term=apache%2Fincubator-devlake) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
