microsoft/qlib · error · ValueError

type is invalid, {}

Error message

type is invalid, {}

What it means

Raised by OnlineOperator.check (operator.py:186) when the type argument is not 'SIM' or 'YC'. The check step supports a fixed vocabulary of executors; 'SIM' selects SimulatorExecutor, and although 'YC' passes this gate it has no implementation on the current code path (see error 315/316).

Source

Thrown at qlib/contrib/online/operator.py:186

                trade_date=trade_date,
            )
            self.logger.info("execute order list at {} for {}".format(trade_date.date(), user_id))

    def update(self, date, path, type="SIM"):
        """Update account at 'date'.

        Parameters
        ----------
        date : str (YYYY-MM-DD)
            Trade date, that the generated order list will be traded.
        path : str
            Path to save user account.
        type : str
            which executor was been used to execute the order list
            'SIM': SimulatorExecutor()
        """
        if type not in ["SIM", "YC"]:
            raise ValueError("type is invalid, {}".format(type))
        um, pred_date, trade_date = self.init(self.client, path, date)
        for user_id, user in um.users.items():
            dates, trade_exchange = prepare(um, trade_date, user_id)
            if type == "SIM":
                executor = SimulatorExecutor(trade_exchange=trade_exchange)
            else:
                raise ValueError("not found executor")
            # dates[0] is the last_trading_date
            if str(dates[0].date()) > str(pred_date.date()):
                raise ValueError(
                    "The account data is not newest! last trading date {}, today {}".format(
                        dates[0].date(), trade_date.date()
                    )
                )
            # load trade info and update account
            trade_info = executor.load_trade_info_from_executed_file(
                user_path=(pathlib.Path(path) / user_id), trade_date=trade_date
            )

View on GitHub (pinned to 79633dd950)

Solutions

  1. Use type='SIM' for the simulator executor (exact uppercase).
  2. Double-check casing — 'sim'/'Sim' are rejected.
  3. Do not use 'YC' for now: it passes validation but immediately hits the separate 'not found executor' error.

Example fix

# before
op.check(date=d, path=p, type="simulator")  # ValueError: type is invalid, simulator

# after
op.check(date=d, path=p, type="SIM")
Defensive patterns

Strategy: type-guard

Validate before calling

TYPE = "SIM"  # only 'SIM' is actually implemented
if TYPE not in ("SIM",):
    raise ValueError(f"unsupported executor type {TYPE!r}")
op.check(date=d, path=p, type=TYPE)

Type guard

def valid_executor_type(t: str) -> bool:
    return isinstance(t, str) and t == "SIM"

Prevention

When it happens

Trigger: Calling op.check(..., type='simulator'), type='backtest', or any string other than exactly 'SIM'/'YC' (the comparison is case-sensitive).

Common situations: Passing lowercase variants like 'sim'; guessing an executor name from docs; carrying a config value with different casing from an older/newer version of the API.

Related errors


AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15). Data as JSON: /api/errors/454a6fa8598c9278. Report an issue: GitHub.