Persistent "Invalid access_token" Error in Async App, Despite Successful Authentication and Working

zackakshay
I am encountering a persistent Invalid 'api_key' or 'access_token' error when trying to place an order from a long-running asynchronous Python application. I am confident my api_key and api_secret are correct because a separate, simple synchronous test script works perfectly. The issue only occurs in my main asyncio-based trading bot, and I have exhausted all logical solutions related to code structure and state management.

My main application (trading_bot.py) successfully authenticates, generates an access_token, and runs its logic. However, when it tries to place an order (sometimes minutes after authentication), the call to kite.place_order() fails with an Invalid access_token error.

The paradox is that a minimal, synchronous test script (test_fno_order.py) using the exact same credentials and configuration can successfully authenticate and place an F&O order every single time.

This suggests the issue is not with the credentials themselves, but a subtle interaction between the KiteConnect session and the asyncio event loop/threading model in a long-running application.

Environment Details

Library: kiteconnect-python (latest version)
Language: Python 3.11.12
Framework: asyncio
Platform: macOS
Error Log & Traceback
The following log appears consistently. Note the diagnostic message confirming the token being used, followed by the immediate API rejection.

2025-06-18 12:13:01,948 - INFO - PRIMARY SIGNAL 'SELL' detected, proceeding with trade.
2025-06-18 12:13:02,123 - INFO - Trade details calculated: Symbol=NIFTY2561924800PE, LotSize=75, Quantity=150
2025-06-18 12:13:02,124 - INFO - Placing LIVE order -> {'tradingsymbol': 'NIFTY2561924800PE', ...}
2025-06-18 12:13:02,124 - INFO - Re-authenticating original Kite session before placing order...
2025-06-18 12:13:02,124 - INFO - DIAGNOSTIC: Token being used for trade: C6BSdYxDZzK10vUi2nD4yJIMUjE5hVRI
2025-06-18 12:13:02,320 - ERROR - Failed to place live order for NIFTY2561924800PE: Invalid `api_key` or `access_token`.
Traceback (most recent call last):
  File "/Users/userName/Desktop/zerodha-trading-bot/agents.py", line 58, in place_trade
    order_id = await asyncio.to_thread(self.kite.place_order, **order_params)
  File "/Users/userName/Desktop/zerodha-trading-bot/trade_bot/lib/python3.11/site-packages/kiteconnect/connect.py", line 937, in _request
    raise exp(data["message"], code=r.status_code)
kiteconnect.exceptions.InputException: Invalid `api_key` or `access_token`.
Solutions Already Attempted (Without Success)

I have tried multiple robust solutions to ensure the KiteConnect object state is valid, but all result in the same error:

Explicit set_access_token(): Ensured kite.set_access_token() is called immediately after generate_session().
Deferred Initialization: Re-architected the application to initialize the OrderExecutionAgent only after a successful authentication, passing it a pre-authenticated kite object.
Just-in-Time Authentication: Re-set the access_token on the original kite object immediately before the place_order call inside the place_trade function.
Fresh Instance (Brute-Force): Created a brand new KiteConnect instance inside place_trade, authenticated it, and used it for the single API call. This also failed with the same error.
Environment Cleaning: Cleared all __pycache__ directories to rule out stale code.
Relevant Code Snippets

This is the place_trade function in agents.py with the latest attempted fix (just-in-time re-authentication), which still fails.

Python

# From agents.py
async def place_trade(self, direction):
symbol, qty = await self._get_trade_details(direction)
# ...
try:
order_params = { ... }
logging.info(f"Placing LIVE order -> {order_params}")

# This is the latest attempted fix
logging.info("Re-authenticating original Kite session before placing order...")
token_to_use = self.config['zerodha']['access_token']
logging.info(f"DIAGNOSTIC: Token being used for trade: {token_to_use}")
self.kite.set_access_token(token_to_use)

# The API call is made in a separate thread
order_id = await asyncio.to_thread(self.kite.place_order, **order_params)
# ...
except Exception as e:
logging.error(f"Failed to place live order for {symbol}: {e}", exc_info=True)
return None
My Questions for the Community

Is there a known issue or limitation when using an access_token in a long-running asyncio application where the API call is delegated to a worker thread?
Could the access_token be implicitly tied to more than just the api_key (e.g., the original requests.Session object, IP address, or user-agent) which gets lost when the call is made from a different thread context?
Is there a session invalidation rule (e.g., if another login occurs on Web or Mobile) that could be causing this, and if so, what is the best practice for handling it in a bot that needs to run for an entire day?
Any insight or guidance would be greatly appreciated, as I have exhausted all debugging paths within my application's logic.

Thank you.
  • Nivas
    Can you run KiteConnect in debug mode and post the complete stacktrace in a private message?
  • zackakshay
    sent the same Nivas, thanks for reaching out!
Sign In or Register to comment.