HKUDS/Vibe-Trading · error · TigerConfigError

invalid Tiger config at {path}: {exc}

Error message

invalid Tiger config at {path}: {exc}

What it means

load_config reads the Tiger settings JSON from config_path() and wraps any OSError, ValueError, or json.JSONDecodeError into TigerConfigError with the offending path. Missing files are not an error (returns an empty TigerConfig); this fires only when the file exists but cannot be read/parsed, or when from_mapping rejects its contents.

Source

Thrown at agent/src/trading/connectors/tiger/sdk.py:162

    cfg = TigerConfig.from_mapping(base)
    clean = {k: v for k, v in dict(overrides or {}).items() if k in _OVERRIDE_KEYS and v not in (None, "")}
    return cfg.with_overrides(**clean) if clean else cfg


def config_path() -> Path:
    """Return the user-level Tiger config path."""
    return get_runtime_root() / CONFIG_FILENAME


def load_config() -> TigerConfig:
    """Load Tiger settings from ``~/.vibe-trading/tiger.json``."""
    path = config_path()
    if not path.exists():
        return TigerConfig()
    try:
        return TigerConfig.from_mapping(json.loads(path.read_text(encoding="utf-8")))
    except (OSError, ValueError, json.JSONDecodeError) as exc:
        raise TigerConfigError(f"invalid Tiger config at {path}: {exc}") from exc


def save_config(config: TigerConfig) -> Path:
    """Persist Tiger settings with owner-only permissions."""
    path = config_path()
    path.parent.mkdir(parents=True, exist_ok=True)
    path.write_text(json.dumps(asdict(config), indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
    try:
        path.chmod(0o600)
    except OSError:
        pass
    return path


def tigeropen_available() -> bool:
    """Return whether the optional ``tigeropen`` SDK can be imported."""
    try:
        _require_tigeropen()

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Run python -m json.tool on the config file to locate and fix the JSON syntax error
  2. Fix permissions (chmod 600, chown to the running user) if OSError is the cause
  3. If the error message contains 'profile must be...', correct the profile value per from_mapping rules
  4. As a last resort delete the file (load_config will return defaults) and re-run save_config with valid settings

Example fix

# before
$ cat ~/.config/.../tiger.json
{"profile": "live", "tiger_id": "123",,}

# after
{"profile": "live", "tiger_id": "123"}
Defensive patterns

Strategy: try-catch

Validate before calling

import json
from pathlib import Path

def config_loads(path: Path) -> bool:
    if not path.exists():
        return True  # absent file is fine
    try:
        json.loads(path.read_text(encoding='utf-8'))
        return True
    except (OSError, ValueError):
        return False

Try / catch

try:
    cfg = load_config()
except TigerConfigError as exc:
    logger.warning('Tiger config unreadable (%s); falling back to defaults', exc)
    cfg = TigerConfig()  # or quarantine the bad file and re-create it

Prevention

When it happens

Trigger: Calling load_config when the JSON file at config_path() is malformed (truncated, BOM issues, trailing commas), unreadable due to permissions, or contains values that fail TigerConfig.from_mapping validation (e.g. bad profile).

Common situations: Concurrent writes corrupting the config file, manual edits leaving invalid JSON, restrictive file permissions (e.g. root-owned file after running with sudo), or a partially-written file from a crashed save_config.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/366c8c6fabcb6bd6. Report an issue: GitHub.