google-research/timesfm · error · ValueError

At least one of dynamic_numerical_covariates, dynamic_catego

Error message

At least one of dynamic_numerical_covariates, dynamic_categorical_covariates, static_numerical_covariates, static_categorical_covariates must be set.

What it means

`forecast_with_covariates()` exists solely to model covariates alongside the base forecast; calling it with all four covariate dicts (dynamic_numerical_covariates, dynamic_categorical_covariates, static_numerical_covariates, static_categorical_covariates) empty gives it nothing to do, so it raises ValueError. Use the plain `forecast()` method when you have no covariates.

Source

Thrown at src/timesfm/timesfm_2p5/timesfm_2p5_base.py:254

      the outputs of the xreg.
    """
    if self.forecast_config is None:
      raise ValueError("Model is not compiled. Please call compile() first.")
    elif not self.forecast_config.return_backcast:
      raise ValueError(
        "For XReg, `return_backcast` must be set to True in the forecast config. Please recompile the model."
      )

    from ..utils import xreg_lib

    # Verify and bookkeep covariates.
    if not (
      dynamic_numerical_covariates
      or dynamic_categorical_covariates
      or static_numerical_covariates
      or static_categorical_covariates
    ):
      raise ValueError(
        "At least one of dynamic_numerical_covariates,"
        " dynamic_categorical_covariates, static_numerical_covariates,"
        " static_categorical_covariates must be set."
      )

    # Track the lengths of (1) each input, (2) the part that can be used in the
    # linear model, and (3) the horizon.
    input_lens, train_lens, test_lens = [], [], []

    for i, input_ts in enumerate(inputs):
      input_len = len(input_ts)
      input_lens.append(input_len)

      if xreg_mode == "timesfm + xreg":
        # For fitting residuals, no TimesFM forecast on the first patch.
        train_lens.append(max(0, input_len - self.model.p))
      elif xreg_mode == "xreg + timesfm":
        train_lens.append(input_len)

View on GitHub (pinned to 331c6d33cb)

Solutions

  1. Pass at least one non-empty covariate dict to forecast_with_covariates
  2. If you have no covariates, call `model.forecast(horizon, inputs)` instead
  3. Add an assertion/check that the covariate dicts are non-empty before the call

Example fix

// before
outs = model.forecast_with_covariates(horizon, inputs, freq, horizon_len,
    dynamic_numerical_covariates={}, dynamic_categorical_covariates={})
// after
outs = model.forecast_with_covariates(horizon, inputs, freq, horizon_len,
    dynamic_numerical_covariates={'temp': covariate_array})
Defensive patterns

Strategy: validation

Validate before calling

covs = [dynamic_numerical_covariates, dynamic_categorical_covariates, static_numerical_covariates, static_categorical_covariates]
if not any(c for c in covs):
    raise ValueError('No covariates supplied; use model.forecast() instead of forecast_with_covariates()')

Type guard

def has_covariates(**kw) -> bool:
    return any(kw.get(k) for k in ('dynamic_numerical_covariates','dynamic_categorical_covariates','static_numerical_covariates','static_categorical_covariates'))

Try / catch

try:
    outputs = model.forecast_with_covariates(...)
except ValueError as e:
    if 'At least one of' in str(e):
        outputs = model.forecast(horizon, inputs)  # fall back to plain forecasting
    else:
        raise

Prevention

When it happens

Trigger: Calling `forecast_with_covariates` with default (None/empty) covariate arguments; covariates loaded conditionally (e.g. empty dict because a file/feature store returned nothing) and then passed in; programmatically building covariate dicts that end up empty.

Common situations: Feature pipeline returned no rows; typo in covariate dict keys so the populated dict is a different variable; switching code from forecast() to forecast_with_covariates() without passing actual covariates; future covariates available but not passed because of a merge/join failure.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of google-research/timesfm@331c6d33cb (2026-08-29). Data as JSON: /api/errors/c63d70ddf1b41a7b. Report an issue: GitHub.