google-research/timesfm · error · ValueError

Activation: {config.activation} not supported.

Error message

Activation: {config.activation} not supported.

What it means

ResidualBlock builds its activation by exact string match on config.activation, which must be one of 'relu', 'swish', or 'none'. Any other string raises ValueError in __init__, guarding against typos that would otherwise silently pick a wrong activation.

Source

Thrown at src/timesfm/torch/dense.py:51

    )
    self.output_layer = nn.Linear(
        in_features=config.hidden_dims,
        out_features=config.output_dims,
        bias=config.use_bias,
    )
    self.residual_layer = nn.Linear(
        in_features=config.input_dims,
        out_features=config.output_dims,
        bias=config.use_bias,
    )
    if config.activation == "relu":
      self.activation = nn.ReLU()
    elif config.activation == "swish":
      self.activation = nn.SiLU()
    elif config.activation == "none":
      self.activation = nn.Identity()
    else:
      raise ValueError(f"Activation: {config.activation} not supported.")

  def forward(self, x: torch.Tensor) -> torch.Tensor:
    return self.output_layer(
        self.activation(self.hidden_layer(x))
    ) + self.residual_layer(x)


class RandomFourierFeatures(nn.Module):
  """Random Fourier features layer."""

  def __init__(self, config: configs.RandomFourierFeaturesConfig):
    super().__init__()
    self.config = config

    if config.output_dims % 4 != 0:
      raise ValueError(
          f"Output dims must be a multiple of 4: {config.output_dims} % 4 != 0."
      )

View on GitHub (pinned to 331c6d33cb)

Solutions

  1. Set activation to one of the supported strings: "relu", "swish", or "none".
  2. If you meant silu/gelu, use "swish" (SiLU) — gelu is not supported in this layer.
  3. Check for typos, casing, and stray whitespace in the config string.
  4. To support another activation, add a branch in src/timesfm/torch/dense.py (e.g. nn.GELU()) rather than passing an unsupported string.

Example fix

// before
config = ResidualBlockConfig(input_dims=64, hidden_dims=1280, output_dims=1280, activation="gelu")
// after
config = ResidualBlockConfig(input_dims=64, hidden_dims=1280, output_dims=1280, activation="swish")
Defensive patterns

Strategy: validation

Validate before calling

SUPPORTED = {"relu", "swish", "none"}
assert config.activation in SUPPORTED, f"activation must be one of {SUPPORTED}"

Try / catch

try:
    block = ResidualBlock(config)
except ValueError as e:
    if "Activation" in str(e):
        config = dataclasses.replace(config, activation="swish")
        block = ResidualBlock(config)
    else:
        raise

Prevention

When it happens

Trigger: Constructing ResidualBlock (or building the TimesFM 2.5 model from a config) with ResidualBlockConfig(activation=<anything other than "relu"|"swish"|"none">) — e.g. "gelu", "silu", or "swish " with trailing whitespace.

Common situations: Porting configs from libraries supporting more activations (gelu, tanh); hand-editing config dataclasses; wrong casing ('Swish','RELU'); building custom model definitions modeled on TimesFM_2p5_200M_Definition.

Related errors


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