google-research/timesfm · error · ValueError

Forecast horizon length inferred from the dynamic covariates

Error message

Forecast horizon length inferred from the dynamic covariates is longer than themax_horizon defined in the forecast config: {test_lens[-1]} > {self.forecast_config.max_horizon=}.

What it means

When dynamic covariates are given, the forecast horizon per input is inferred as len(covariate_series) - len(input). If that inferred length exceeds the `max_horizon` baked into the compiled ForecastConfig, the compiled decode kernel cannot produce that many steps, so the library raises ValueError. max_horizon is fixed at compile time and cannot be exceeded at inference.

Source

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

        train_lens.append(max(0, input_len - self.model.p))
      elif xreg_mode == "xreg + timesfm":
        train_lens.append(input_len)
      else:
        raise ValueError(f"Unsupported mode: {xreg_mode}")

      if dynamic_numerical_covariates:
        test_lens.append(
          len(list(dynamic_numerical_covariates.values())[0][i]) - input_len
        )
      elif dynamic_categorical_covariates:
        test_lens.append(
          len(list(dynamic_categorical_covariates.values())[0][i]) - input_len
        )
      else:
        test_lens.append(self.forecast_config.max_horizon)

      if test_lens[-1] > self.forecast_config.max_horizon:
        raise ValueError(
          "Forecast horizon length inferred from the dynamic covariates is longer than the"
          f"max_horizon defined in the forecast config: {test_lens[-1]} > {self.forecast_config.max_horizon=}."
        )

    # Prepare the covariates into train and test.
    train_dynamic_numerical_covariates = collections.defaultdict(list)
    test_dynamic_numerical_covariates = collections.defaultdict(list)
    train_dynamic_categorical_covariates = collections.defaultdict(list)
    test_dynamic_categorical_covariates = collections.defaultdict(list)
    for covariates, train_covariates, test_covariates in (
      (
        dynamic_numerical_covariates,
        train_dynamic_numerical_covariates,
        test_dynamic_numerical_covariates,
      ),
      (
        dynamic_categorical_covariates,
        train_dynamic_categorical_covariates,

View on GitHub (pinned to 331c6d33cb)

Solutions

  1. Recompile with `ForecastConfig(max_horizon=<larger value>)` to cover the inferred horizon
  2. Trim the dynamic covariate series so len(cov) - len(input) <= max_horizon
  3. Note max_horizon is also bounded by context_limit (see the context+horizon check), so keep max_context + max_horizon within it

Example fix

// before
config = ForecastConfig(max_context=512, max_horizon=64, return_backcast=True)
model.compile(forecast_config=config)
model.forecast_with_covariates(..., dynamic_numerical_covariates={'x': arr_of_len_1024})
// after
config = ForecastConfig(max_context=512, max_horizon=256, return_backcast=True)
model.compile(forecast_config=config)
model.forecast_with_covariates(..., dynamic_numerical_covariates={'x': arr_of_len_1024})
Defensive patterns

Strategy: validation

Validate before calling

first_dyn = next(iter(dynamic_numerical_covariates.values())) if dynamic_numerical_covariates else next(iter(dynamic_categorical_covariates.values()))
inferred_horizon = len(first_dyn[0]) - len(inputs[0])
if inferred_horizon > model.forecast_config.max_horizon:
    model.compile(forecast_config=dataclasses.replace(model.forecast_config, max_horizon=inferred_horizon))

Type guard

def horizon_fits(covariate_len: int, input_len: int, max_horizon: int) -> bool:
    return (covariate_len - input_len) <= max_horizon

Prevention

When it happens

Trigger: Supplying dynamic covariate arrays longer than len(input) + max_horizon; compiling with a small max_horizon then passing covariates expecting a longer future; differing covariate lengths across inputs where one exceeds max_horizon.

Common situations: Covariate forecasts generated by another model extended further out than the compiled horizon; forgetting to recompile after increasing the desired forecast length; unit mismatch (hourly covariates vs daily expectations).

Related errors


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