{"record":{"id":"e57f9902fe57f772","repo":"google-research/timesfm","slug":"unsupported-mode-xreg-mode","errorCode":null,"errorMessage":"Unsupported mode: {xreg_mode}","messagePattern":"Unsupported mode: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/timesfm/timesfm_2p5/timesfm_2p5_base.py","lineNumber":274,"sourceCode":"        \" dynamic_categorical_covariates, static_numerical_covariates,\"\n        \" static_categorical_covariates must be set.\"\n      )\n\n    # Track the lengths of (1) each input, (2) the part that can be used in the\n    # linear model, and (3) the horizon.\n    input_lens, train_lens, test_lens = [], [], []\n\n    for i, input_ts in enumerate(inputs):\n      input_len = len(input_ts)\n      input_lens.append(input_len)\n\n      if xreg_mode == \"timesfm + xreg\":\n        # For fitting residuals, no TimesFM forecast on the first patch.\n        train_lens.append(max(0, input_len - self.model.p))\n      elif xreg_mode == \"xreg + timesfm\":\n        train_lens.append(input_len)\n      else:\n        raise ValueError(f\"Unsupported mode: {xreg_mode}\")\n\n      if dynamic_numerical_covariates:\n        test_lens.append(\n          len(list(dynamic_numerical_covariates.values())[0][i]) - input_len\n        )\n      elif dynamic_categorical_covariates:\n        test_lens.append(\n          len(list(dynamic_categorical_covariates.values())[0][i]) - input_len\n        )\n      else:\n        test_lens.append(self.forecast_config.max_horizon)\n\n      if test_lens[-1] > self.forecast_config.max_horizon:\n        raise ValueError(\n          \"Forecast horizon length inferred from the dynamic covariates is longer than the\"\n          f\"max_horizon defined in the forecast config: {test_lens[-1]} > {self.forecast_config.max_horizon=}.\"\n        )\n","sourceCodeStart":256,"sourceCodeEnd":292,"githubUrl":"https://github.com/google-research/timesfm/blob/331c6d33cb1ac2611de3056d0ac7164aab6301eb/src/timesfm/timesfm_2p5/timesfm_2p5_base.py#L256-L292","documentation":"`xreg_mode` must be exactly 'timesfm + xreg' or 'xreg + timesfm'; any other string (the f-string interpolates the offending value) is rejected with ValueError. The mode controls whether the residual model is fit on the pre-patch context ('timesfm + xreg') or the full input ('xreg + timesfm'), and unknown modes have no defined behavior. This is a strict enum-style validation of a string argument.","triggerScenarios":"Passing xreg_mode values like 'xreg', 'timesfm+xreg' (missing spaces), 'TimesFM + XReg' (wrong case), or None; an application config file supplying a custom mode name; upgrading from TimesFM 1.x where covariate API had different parameter semantics.","commonSituations":"Typo or inconsistent spacing/casing in the mode string; reading the mode from CLI/config without validating against allowed values; mixing examples from different TimesFM versions.","solutions":["Use exactly 'timesfm + xreg' or 'xreg + timesfm' (lowercase, with spaces around '+')","Validate the mode string against an allowlist before calling","If you don't need residual covariate modeling, use plain forecast() instead"],"exampleFix":"// before\nmodel.forecast_with_covariates(..., xreg_mode='timesfm+xreg', ...)\n// after\nmodel.forecast_with_covariates(..., xreg_mode='timesfm + xreg', ...)","handlingStrategy":"validation","validationCode":"ALLOWED_XREG_MODES = {'timesfm + xreg', 'xreg + timesfm'}\nif xreg_mode not in ALLOWED_XREG_MODES:\n    raise ValueError(f'xreg_mode must be one of {ALLOWED_XREG_MODES}, got {xreg_mode!r}')","typeGuard":"from typing import Literal\nXregMode = Literal['timesfm + xreg', 'xreg + timesfm']\ndef is_valid_xreg_mode(mode: str) -> bool:\n    return mode in ('timesfm + xreg', 'xreg + timesfm')","tryCatchPattern":null,"preventionTips":["Define xreg_mode as a Literal/enum in your app config and validate at load time","Copy mode strings exactly (lowercase, spaces around '+') from the docs","Unit-test any config-to-API mapping that produces xreg_mode"],"tags":["python","invalid-argument","enum","xreg"],"backgroundTag":"invalid-enum-value","analyzedSha":"331c6d33cb1ac2611de3056d0ac7164aab6301eb","analyzedAt":"2026-08-29T01:04:23.138Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}