yikart/AiToEarn · error · AppException
ResponseCode.ChannelAuthSessionInvalid
ResponseCode.ChannelAuthSessionInvalid
Error message
ChannelAuthSessionInvalid
What it means
Thrown in AuthService.completeCallback when the Redis record for the given session ID is not a valid account-auth session (isAccountAuthSessionRecord fails or the key is missing). The stored AuthSession is the only proof that this callback belongs to a legitimately started authorization flow.
Source
Thrown at project/aitoearn-backend/apps/aitoearn-server/src/core/channels/auth/auth.service.ts:106
await this.redis.saveChannelAuthSession(session.id, session)
return {
url: result.url,
sessionId,
expiresAt,
authInstructions: integration.metadata.authInstructions,
}
}
async completeCallback(
platform: AccountType,
callbackInput: Omit<AuthCallbackInput, 'session'>,
sessionId: string,
): Promise<AuthCallbackResult> {
const session = await this.redis.getChannelAuthSession<AuthSession>(sessionId)
if (!this.isAccountAuthSessionRecord(session)) {
throw new AppException(ResponseCode.ChannelAuthSessionInvalid)
}
if (this.isSessionExpired(session)) {
throw new AppException(ResponseCode.ChannelAuthSessionInvalid)
}
if (session.platform !== platform) {
throw new AppException(ResponseCode.ChannelAuthPlatformMismatch)
}
if (session.status !== ChannelAuthSessionStatus.Pending) {
throw new AppException(ResponseCode.ChannelAuthSessionCompleted)
}
const provider = this.registry.getAuth(platform)
const credentialResult = await provider.exchangeCode({
...callbackInput,
session,
})
const credentialContext = credentialResult.accessTokenView on GitHub (pinned to d3aa8bea5b)
Solutions
- Restart the channel auth flow to generate a fresh session and use its state/sessionId for the callback.
- Check Redis connectivity and that the instance holding the session is the one the server reads (verify REDIS config/env per environment).
- Increase the session TTL if users take long between starting auth and completing the provider login.
- Confirm the callback passes the exact state echoed by the provider — no truncation or re-encoding of the session ID.
Example fix
// before: retrying a stale callback after Redis restart
await authService.completeCallback(platform, callbackInput, oldSessionId)
// after: detect and restart the flow
try {
await authService.completeCallback(platform, callbackInput, sessionId)
}
catch (e) {
if (getErrorCode(e) === ResponseCode.ChannelAuthSessionInvalid) {
const fresh = await authService.generateAuthUrl(...) // new session + state
}
} Defensive patterns
Strategy: try-catch
Try / catch
try {
await authService.completeCallback(platform, callbackInput, sessionId)
}
catch (e) {
if (getErrorCode(e) === ResponseCode.ChannelAuthSessionInvalid) {
await restartAuthFlow(userId, platform) // fresh session + state
}
} Prevention
- Use a persistent Redis (AOF/RDB) for auth sessions
- Pin one Redis instance per environment and verify env config
- Never reuse state values across flows
- Monitor Redis eviction/maxmemory settings
When it happens
Trigger: completeCallback is called with a sessionId that: was never created (bogus state), was deleted by Redis eviction/TTL, is a different session type (not AccountAuth flow), or the Redis database was flushed/restarted without persistence.
Common situations: Redis restart or eviction losing the session; reusing an old state value after the flow was restarted; switching Redis DBs/instances between environments (e.g. staging vs prod URL); TTL expiry misread as 'invalid' by the developer.
Related errors
- 无效的状态码
- ResponseCode.ChannelAuthPlatformMismatch
- ResponseCode.ChannelAuthSessionCompleted
- ResponseCode.ChannelAuthSelectableAccountsNotFound
- 无效的状态参数或状态已过期
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/d43b3de355fe6f05.
Report an issue: GitHub.