{"record":{"id":"630efddca1d6b056","repo":"google-research/timesfm","slug":"context-horizon-must-be-less-than-the-context-li-630efd","errorCode":null,"errorMessage":"Context + horizon must be less than the context limit. {fc.max_context} + {fc.max_horizon} > {self.model.config.context_limit}.","messagePattern":"Context \\+ horizon must be less than the context limit\\. (.+?) \\+ (.+?) > (.+?)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/timesfm/timesfm_2p5/timesfm_2p5_torch.py","lineNumber":410,"sourceCode":"\n    if fc.max_context % self.model.p != 0:\n      logging.info(\n        \"When compiling, max context needs to be multiple of the patch size\"\n        \" %d. Using max context = %d instead.\",\n        self.model.p,\n        new_context := math.ceil(fc.max_context / self.model.p) * self.model.p,\n      )\n      fc = dataclasses.replace(fc, max_context=new_context)\n    if fc.max_horizon % self.model.o != 0:\n      logging.info(\n        \"When compiling, max horizon needs to be multiple of the output patch\"\n        \" size %d. Using max horizon = %d instead.\",\n        self.model.o,\n        new_horizon := math.ceil(fc.max_horizon / self.model.o) * self.model.o,\n      )\n      fc = dataclasses.replace(fc, max_horizon=new_horizon)\n    if fc.max_context + fc.max_horizon > self.model.config.context_limit:\n      raise ValueError(\n        \"Context + horizon must be less than the context limit.\"\n        f\" {fc.max_context} + {fc.max_horizon} >\"\n        f\" {self.model.config.context_limit}.\"\n      )\n    if fc.use_continuous_quantile_head and (fc.max_horizon > self.model.os):\n      raise ValueError(\n        f\"Continuous quantile head is not supported for horizons > {self.model.os}.\"\n      )\n    self.forecast_config = fc\n\n    def _compiled_decode(horizon, inputs, masks):\n      if horizon > fc.max_horizon:\n        raise ValueError(\n          f\"Horizon must be less than the max horizon. {horizon} > {fc.max_horizon}.\"\n        )\n\n      inputs = (\n        torch.from_numpy(np.array(inputs)).to(self.model.device).to(torch.float32)","sourceCodeStart":392,"sourceCodeEnd":428,"githubUrl":"https://github.com/google-research/timesfm/blob/331c6d33cb1ac2611de3056d0ac7164aab6301eb/src/timesfm/timesfm_2p5/timesfm_2p5_torch.py#L392-L428","documentation":"During compile(), TimesFM validates the forecast_config: max_context + max_horizon must not exceed the model's context_limit (16384 for TimesFM 2.5 200M). Context and horizon share one positional budget, so requesting too much total window would exceed the compiled sequence length. Note max_context/max_horizon are first rounded up to patch-size multiples (patch 32, output patch 128), which can push an otherwise-valid config over the limit.","triggerScenarios":"Calling model.compile(forecast_config) where, after rounding, fc.max_context + fc.max_horizon > 16384 — e.g. max_context=16384 with any nonzero horizon, or max_context=16320 + max_horizon=128 (sum 16448 > 16384).","commonSituations":"Forecasting near-limit-length series while also requesting a long horizon; forgetting horizons round up to multiples of 128; copying configs from a model with a larger context limit.","solutions":["Reduce max_context and/or max_horizon so their sum is <= 16384.","Compute rounded values before compiling: context must be a multiple of 32, horizon a multiple of 128; verify rounded_context + rounded_horizon <= 16384.","Keep a safety margin (e.g. sum <= 16000) to absorb rounding.","Split very long series into windows and forecast iteratively instead of compiling above the limit."],"exampleFix":"// before\nfc = ForecastConfig(max_context=16384, max_horizon=256)\nmodel.compile(fc)  # ValueError: 16384 + 256 > 16384\n// after\nfc = ForecastConfig(max_context=16128, max_horizon=256)  # 16128+256 = 16384 <= limit\nmodel.compile(fc)","handlingStrategy":"validation","validationCode":"CONTEXT_LIMIT = 16384\nctx = math.ceil(fc.max_context / 32) * 32\nhor = math.ceil(fc.max_horizon / 128) * 128\nassert ctx + hor <= CONTEXT_LIMIT, f\"{ctx}+{hor} exceeds context limit\"","typeGuard":null,"tryCatchPattern":"try:\n    model.compile(fc)\nexcept ValueError as e:\n    if \"context limit\" in str(e):\n        fc = dataclasses.replace(fc, max_context=fc.max_context - 256)\n        model.compile(fc)\n    else:\n        raise","preventionTips":["Keep max_context + max_horizon <= 16384 with margin for patch rounding.","Remember context rounds to multiples of 32 and horizon to multiples of 128.","Compute the padded values programmatically before compile.","Avoid copying configs from models with larger context limits."],"tags":["configuration","value-error","context-limit","forecasting"],"backgroundTag":"context-length-exceeds-limit","analyzedSha":"331c6d33cb1ac2611de3056d0ac7164aab6301eb","analyzedAt":"2026-08-29T01:04:23.138Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}