{"record":{"id":"f08c0f0138f1c6e1","repo":"microsoft/qlib","slug":"unknown-rnn-type-s-f08c0f","errorCode":null,"errorMessage":"unknown rnn_type `%s`","messagePattern":"unknown rnn_type `(.+?)`","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"qlib/contrib/model/pytorch_alstm_ts.py","lineNumber":322,"sourceCode":"\n        return pd.Series(np.concatenate(preds), index=dl_test.get_index())\n\n\nclass ALSTMModel(nn.Module):\n    def __init__(self, d_feat=6, hidden_size=64, num_layers=2, dropout=0.0, rnn_type=\"GRU\"):\n        super().__init__()\n        self.hid_size = hidden_size\n        self.input_size = d_feat\n        self.dropout = dropout\n        self.rnn_type = rnn_type\n        self.rnn_layer = num_layers\n        self._build_model()\n\n    def _build_model(self):\n        try:\n            klass = getattr(nn, self.rnn_type.upper())\n        except Exception as e:\n            raise ValueError(\"unknown rnn_type `%s`\" % self.rnn_type) from e\n        self.net = nn.Sequential()\n        self.net.add_module(\"fc_in\", nn.Linear(in_features=self.input_size, out_features=self.hid_size))\n        self.net.add_module(\"act\", nn.Tanh())\n        self.rnn = klass(\n            input_size=self.hid_size,\n            hidden_size=self.hid_size,\n            num_layers=self.rnn_layer,\n            batch_first=True,\n            dropout=self.dropout,\n        )\n        self.fc_out = nn.Linear(in_features=self.hid_size * 2, out_features=1)\n        self.att_net = nn.Sequential()\n        self.att_net.add_module(\n            \"att_fc_in\",\n            nn.Linear(in_features=self.hid_size, out_features=int(self.hid_size / 2)),\n        )\n        self.att_net.add_module(\"att_dropout\", torch.nn.Dropout(self.dropout))\n        self.att_net.add_module(\"att_act\", nn.Tanh())","sourceCodeStart":304,"sourceCodeEnd":340,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/contrib/model/pytorch_alstm_ts.py#L304-L340","documentation":"The ALSTM internal network builds its recurrent layer by looking up torch.nn for the attribute rnn_type.upper() (e.g. 'gru' -> nn.GRU, 'lstm' -> nn.LSTM). If that attribute does not exist, getattr raises AttributeError which is caught and re-raised as ValueError('unknown rnn_type ...'). Note that any non-RNN nn attribute that happens to match (e.g. 'linear') would pass this check and fail later with a construction TypeError, since the code relies on name lookup rather than an explicit allowlist.","triggerScenarios":"Passing rnn_type='transformer', 'srnn', or any string whose uppercase form is not an nn module name; typos like 'gruu' or '1stm'; a PyTorch version that removed/renamed the requested RNN class (does not happen for GRU/LSTM/RNN but can for exotic names).","commonSituations":"Experimenting with recurrent cell types not supported by the model; copying hyperparameter blocks from a custom fork; case errors ('GRU' works because .upper() normalizes it, but 'gru ' with whitespace fails).","solutions":["Use one of the supported values: 'gru', 'lstm', or 'rnn' (any string whose uppercase matches an nn RNN class).","Verify the exact string has no typos, whitespace, or mixed characters.","If you need a custom recurrent cell, subclass the model and override _build_model to construct self.rnn directly."],"exampleFix":"# before\nmodel = ALSTMTSModel(rnn_type='sru')\n\n# after\nmodel = ALSTMTSModel(rnn_type='gru')","handlingStrategy":"validation","validationCode":"import torch.nn as nn\nassert hasattr(nn, model.rnn_type.upper()), f\"rnn_type {model.rnn_type!r} has no torch.nn counterpart\"","typeGuard":"import torch.nn as nn\n\ndef is_valid_rnn_type(rnn_type: str) -> bool:\n    return hasattr(nn, rnn_type.upper())","tryCatchPattern":"try:\n    model.fit(dataset)\nexcept ValueError as e:\n    if 'unknown rnn_type' in str(e):\n        model.rnn_type = 'gru'\n        model.init_dataset()  # rebuild if applicable\n    raise","preventionTips":["Restrict rnn_type to 'gru'/'lstm'/'rnn' in config schemas.","Validate the string maps to an actual torch.nn RNN class before fit().","Watch for whitespace and lookalike characters in copied configs."],"tags":["pytorch","qlib","config-validation","rnn","alstm"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}