fix: token refresh rate limit (EGW00133) causing cascading failures #54

Closed
opened 2026-02-05 00:35:38 +09:00 by agentson · 0 comments
Collaborator

Problem

KIS API token refresh is attempted too frequently, hitting 1-minute rate limit and causing cascading failures.

Error Log

INFO: Refreshing KIS access token
WARNING: Token refresh failed (403): {"error_description":"접근토큰 발급 잠시 후 다시 시도하세요(1분당 1회)","error_code":"EGW00133"}

Observed pattern:

  • Token refresh attempted for every API call
  • Multiple refresh attempts within seconds
  • All subsequent API calls fail due to stale/missing token
  • Retry logic triggers even more refresh attempts

Root Cause Analysis

Likely causes:

  1. Token not properly cached after successful refresh
  2. Token expiry check missing or incorrect
  3. Concurrent requests triggering multiple refresh attempts
  4. Token refresh lock not working properly (see issue #42)

Impact

  • Severity: HIGH - prevents all trading operations
  • Frequency: Occurs after first API call of the session
  • Markets affected: All markets (domestic + overseas)
  • Consequence: Complete system failure, no trades executed

Current Token Management (src/broker/kis_api.py)

Need to verify:

  • Is token being cached correctly?
  • Is token expiry being checked before refresh?
  • Is the refresh lock from issue #42 working?
  • Are expired tokens being detected properly?

Proposed Solution

1. Add token expiry tracking

class KISBroker:
    def __init__(self):
        self._token_expires_at: float | None = None
        
    async def _ensure_token(self):
        now = time.time()
        if self._token_expires_at and now < self._token_expires_at:
            return  # Token still valid
        
        await self._refresh_token()
        self._token_expires_at = now + 86400  # 24 hours

2. Add cooldown period for failed refreshes

self._last_refresh_attempt = 0
self._refresh_cooldown = 60  # seconds

if time.time() - self._last_refresh_attempt < self._refresh_cooldown:
    raise ConnectionError("Token refresh on cooldown")

3. Log token status for debugging

logger.debug("Token status: cached=%s, expires_in=%ds", 
             bool(self._token), expires_in)

Investigation Required

  1. Read src/broker/kis_api.py token management code
  2. Check if token expiry is tracked
  3. Verify refresh lock is working (from #42)
  4. Test token lifecycle: fresh → valid → expired → refresh
  5. Add comprehensive logging for token state changes

Success Criteria

  • Token refreshed at most once per minute
  • Successful API calls use cached token
  • Token expiry detected before making API calls
  • No cascading failures from refresh rate limit
  • Clear logging of token lifecycle events
  • #42 - Token refresh lock (concurrent API calls)
  • This issue - Token refresh rate limit (1/minute)
## Problem KIS API token refresh is attempted too frequently, hitting 1-minute rate limit and causing cascading failures. ## Error Log ``` INFO: Refreshing KIS access token WARNING: Token refresh failed (403): {"error_description":"접근토큰 발급 잠시 후 다시 시도하세요(1분당 1회)","error_code":"EGW00133"} ``` Observed pattern: - Token refresh attempted for every API call - Multiple refresh attempts within seconds - All subsequent API calls fail due to stale/missing token - Retry logic triggers even more refresh attempts ## Root Cause Analysis **Likely causes:** 1. Token not properly cached after successful refresh 2. Token expiry check missing or incorrect 3. Concurrent requests triggering multiple refresh attempts 4. Token refresh lock not working properly (see issue #42) ## Impact - **Severity**: HIGH - prevents all trading operations - **Frequency**: Occurs after first API call of the session - **Markets affected**: All markets (domestic + overseas) - **Consequence**: Complete system failure, no trades executed ## Current Token Management (src/broker/kis_api.py) Need to verify: - Is token being cached correctly? - Is token expiry being checked before refresh? - Is the refresh lock from issue #42 working? - Are expired tokens being detected properly? ## Proposed Solution **1. Add token expiry tracking** ```python class KISBroker: def __init__(self): self._token_expires_at: float | None = None async def _ensure_token(self): now = time.time() if self._token_expires_at and now < self._token_expires_at: return # Token still valid await self._refresh_token() self._token_expires_at = now + 86400 # 24 hours ``` **2. Add cooldown period for failed refreshes** ```python self._last_refresh_attempt = 0 self._refresh_cooldown = 60 # seconds if time.time() - self._last_refresh_attempt < self._refresh_cooldown: raise ConnectionError("Token refresh on cooldown") ``` **3. Log token status for debugging** ```python logger.debug("Token status: cached=%s, expires_in=%ds", bool(self._token), expires_in) ``` ## Investigation Required 1. Read `src/broker/kis_api.py` token management code 2. Check if token expiry is tracked 3. Verify refresh lock is working (from #42) 4. Test token lifecycle: fresh → valid → expired → refresh 5. Add comprehensive logging for token state changes ## Success Criteria - Token refreshed at most once per minute - Successful API calls use cached token - Token expiry detected before making API calls - No cascading failures from refresh rate limit - Clear logging of token lifecycle events ## Related Issues - #42 - Token refresh lock (concurrent API calls) - This issue - Token refresh rate limit (1/minute)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: jihoson/The-Ouroboros#54