HKUDS/Vibe-Trading · critical · ShoonyaConfigError
Shoonya login failed: {error_msg}
Error message
Shoonya login failed: {error_msg} What it means
Raised by the Shoonya connector's _login helper when the NorenApi login call returns None or a payload whose 'stat' field is not 'Ok'. The upstream error message ('emsg') is embedded when present. It is wrapped as ShoonyaConfigError, meaning the connector treats failed credentials/connectivity at login as a configuration problem.
Source
Thrown at agent/src/trading/connectors/shoonya/sdk.py:590
websocket="wss://api.shoonya.com/NorenWSTP/",
)
api = ShoonyaApi()
totp = pyotp.TOTP(cfg.totp_secret).now()
ret = api.login(
userid=cfg.user_id,
password=cfg.password,
twoFA=totp,
vendor_code=cfg.vendor_code,
api_secret=cfg.api_secret,
imei="vibe-trading",
)
if ret is None or ret.get("stat") != "Ok":
error_msg = ret.get("emsg", "Login failed") if ret else "Login returned None"
raise ShoonyaConfigError(f"Shoonya login failed: {error_msg}")
_api_cache[cfg.user_id] = api
return api
def _missing_fields(cfg: ShoonyaConfig) -> list[str]:
missing = []
for field in ("user_id", "password", "vendor_code", "api_secret", "totp_secret"):
if not getattr(cfg, field):
missing.append(field)
return missing
def _public_config(cfg: ShoonyaConfig) -> dict[str, Any]:
data = asdict(cfg)
for secret in ("password", "api_secret", "totp_secret"):
if data.get(secret):
data[secret] = "***redacted***"View on GitHub (pinned to 80ffdda44c)
Solutions
- Verify cfg.user_id, cfg.password, cfg.vendor_token, cfg.api_secret against the Shoonya/Noren developer portal and regenerate the vendor token if stale
- Confirm the TOTP/2FA factor value is current and the imei string matches what is registered
- Check the configured Norden base URL environment (UAT vs production) matches the credentials
- If ret is None, test raw connectivity (curl the Shoonya endpoint) and inspect network/proxy settings
- Catch ShoonyaConfigError at the call site and surface the embedded emsg for the broker-side reason
Example fix
# before
cfg = ShoonyaConfig(user_id='u', password='wrong', ...)
api = _login(cfg) # raises 'Shoonya login failed: ...'
# after
cfg = ShoonyaConfig(user_id='u', password=os.environ['SHOONYA_PASSWORD'],
vendor_token=os.environ['SHOONYA_VENDOR_TOKEN'],
api_secret=os.environ['SHOONYA_API_SECRET']) Defensive patterns
Strategy: try-catch
Validate before calling
from agent.src.trading.connectors.shoonya.sdk import ShoonyaConfigError
def can_login(cfg) -> bool:
missing = _missing_fields(cfg)
if missing:
return False
try:
_login(cfg)
return True
except ShoonyaConfigError:
return False Type guard
def is_shoonya_config_error(exc: BaseException) -> bool:
return isinstance(exc, ShoonyaConfigError) and exc.args[0].startswith('Shoonya login failed') Try / catch
try:
snapshot = get_account_snapshot(cfg)
except ShoonyaConfigError as exc:
if 'login failed' in str(exc):
logger.error('Shoonya auth rejected: %s', exc)
# re-read credentials / alert operator; do not retry in a tight loop
raise Prevention
- Store Shoonya credentials in env vars/secret manager, never hand-edited JSON
- Run a login health-check at service startup (call one cheap endpoint) and fail fast
- Refresh vendor tokens on a schedule before they expire
When it happens
Trigger: Any call to get_account_snapshot, get_positions, get_open_orders, get_quote, or get_historical_bars on a cold (or invalidated) API cache triggers _login; if userid/password/vendor_token/api_secret/imei are wrong, TOTP is stale, or the Noren endpoint is unreachable, ret is None or stat != 'Ok'.
Common situations: Expired or changed Shoonya password, wrong vendor code/token/secret pair, missing TOTP factor, base URL pointing at the wrong environment (uat vs prod), or network/firewall blocking the broker's REST endpoint.
Related errors
- OpenAI Codex OAuth requires oauth-cli-kit. Install dependenc
- TUSHARE_TOKEN not in agent/.env or environment; required for
- connection credential_ref does not match its local transport
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/2a465dd54115c4c3.
Report an issue: GitHub.