HKUDS/Vibe-Trading · error · AlpacaConfigError

invalid Alpaca config at {path}: {exc}

Error message

invalid Alpaca config at {path}: {exc}

What it means

Wrapped error from load_config: the Alpaca config file exists but could not be read (OSError), parsed as JSON (json.JSONDecodeError), or validated by from_mapping (ValueError such as bad profile/feed). The original exception is chained, and the message embeds the file path and underlying reason so you can fix the exact file.

Source

Thrown at agent/src/trading/connectors/alpaca/sdk.py:169

    cfg = AlpacaConfig.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 Alpaca config path."""
    return get_runtime_root() / CONFIG_FILENAME


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


def save_config(config: AlpacaConfig) -> Path:
    """Persist Alpaca 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


# ---------------------------------------------------------------------------
# TAP routing (opt-in credential isolation)
# ---------------------------------------------------------------------------

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Read the {exc} part of the message — it names the exact JSON syntax or validation problem
  2. Validate the file with python -m json.tool <path> to pinpoint syntax errors
  3. Fix invalid field values (profile/feed) per the from_mapping rules
  4. Check file ownership/permissions (config is written owner-only) if the reason is an OSError
  5. As a last resort, delete/rename the file — load_config returns a default AlpacaConfig() when it is absent

Example fix

// before
// ~/.alpaca/config.json contains: {"profile": "paper",}   <- trailing comma
{
  "profile": "paper"
}
Defensive patterns

Strategy: try-catch

Validate before calling

import json
from pathlib import Path
p = config_path()
if p.exists():
    json.loads(p.read_text(encoding="utf-8"))  # raises early with a precise JSON error
# plus verify profile/feed values against the allowed sets before load_config

Try / catch

try:
    config = load_config()
except AlpacaConfigError as exc:
    message = str(exc)
    if "invalid Alpaca config at" in message:
        # parse the embedded {exc}; fall back to defaults if the user consents
        path.rename(path.with_suffix(".json.bak"))
        config = AlpacaConfig()
    else:
        raise

Prevention

When it happens

Trigger: config_path() exists and path.read_text raises (permissions, race deletion), json.loads fails on malformed JSON (trailing comma, comments, truncated file), or from_mapping raises for an invalid profile/feed value — all re-raised as AlpacaConfigError.

Common situations: Hand-edited config with a JSON syntax error (comments, single quotes, trailing commas); file truncated by a crashed save_config; file written with a different user so permissions deny reads; partial manual migration leaving invalid field values.

Related errors


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