diff --git a/src/ExprNode.cc b/src/ExprNode.cc
index 10e9eaa348e273195f4a529c6ef709a2c79565f1..a48de8837c4f87810041297a14951cdc51fffc3f 100644
--- a/src/ExprNode.cc
+++ b/src/ExprNode.cc
@@ -963,10 +963,11 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
     }
 
   int i;
-  switch (int tsid = datatree.symbol_table.getTypeSpecificID(symb_id); type)
+  switch (type)
     {
     case SymbolType::parameter:
-      if (output_type == ExprNodeOutputType::matlabOutsideModel)
+      if (int tsid = datatree.symbol_table.getTypeSpecificID(symb_id);
+          output_type == ExprNodeOutputType::matlabOutsideModel)
         output << "M_.params" << "(" << tsid + 1 << ")";
       else
         output << "params" << LEFT_ARRAY_SUBSCRIPT(output_type) << tsid + ARRAY_SUBSCRIPT_OFFSET(output_type) << RIGHT_ARRAY_SUBSCRIPT(output_type);
@@ -991,7 +992,8 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
       break;
 
     case SymbolType::endogenous:
-      switch (output_type)
+      switch (int tsid = datatree.symbol_table.getTypeSpecificID(symb_id);
+              output_type)
         {
         case ExprNodeOutputType::juliaDynamicModel:
         case ExprNodeOutputType::matlabDynamicModel:
@@ -1038,7 +1040,7 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
       break;
 
     case SymbolType::exogenous:
-      i = tsid + ARRAY_SUBSCRIPT_OFFSET(output_type);
+      i = datatree.symbol_table.getTypeSpecificID(symb_id) + ARRAY_SUBSCRIPT_OFFSET(output_type);
       switch (output_type)
         {
         case ExprNodeOutputType::juliaDynamicModel:
@@ -1096,7 +1098,7 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
       break;
 
     case SymbolType::exogenousDet:
-      i = tsid + datatree.symbol_table.exo_nbr() + ARRAY_SUBSCRIPT_OFFSET(output_type);
+      i = datatree.symbol_table.getTypeSpecificID(symb_id) + datatree.symbol_table.exo_nbr() + ARRAY_SUBSCRIPT_OFFSET(output_type);
       switch (output_type)
         {
         case ExprNodeOutputType::juliaDynamicModel:
@@ -1126,10 +1128,10 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
           break;
         case ExprNodeOutputType::matlabOutsideModel:
           assert(lag == 0);
-          output <<  "oo_.exo_det_steady_state(" << tsid + 1 << ")";
+          output <<  "oo_.exo_det_steady_state(" << datatree.symbol_table.getTypeSpecificID(symb_id) + 1 << ")";
           break;
         case ExprNodeOutputType::matlabDynamicSteadyStateOperator:
-          output <<  "oo_.exo_det_steady_state(" << tsid + 1 << ")";
+          output <<  "oo_.exo_det_steady_state(" << datatree.symbol_table.getTypeSpecificID(symb_id) + 1 << ")";
           break;
         case ExprNodeOutputType::juliaSteadyStateFile:
         case ExprNodeOutputType::steadyStateFile:
diff --git a/src/SymbolTable.cc b/src/SymbolTable.cc
index 895a2849497c8cdb0d5f372ecaee3895010f6586..936a253ad83fa5e5eef3eec483d5990326d17ea4 100644
--- a/src/SymbolTable.cc
+++ b/src/SymbolTable.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2003-2019 Dynare Team
+ * Copyright © 2003-2020 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -130,10 +130,9 @@ SymbolTable::freeze() noexcept(false)
           param_ids.push_back(i);
           break;
         default:
-          tsi = -1;
-          break;
+          continue;
         }
-      type_specific_ids.push_back(tsi);
+      type_specific_ids[i] = tsi;
     }
 }
 
diff --git a/src/SymbolTable.hh b/src/SymbolTable.hh
index 8c3eef32f6ccafb0126853811e754e03fec5e5ff..80171cfb270c7140575ca66d322e5f299c08b5b4 100644
--- a/src/SymbolTable.hh
+++ b/src/SymbolTable.hh
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2003-2019 Dynare Team
+ * Copyright © 2003-2020 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -151,7 +151,7 @@ private:
   vector<SymbolType> type_table;
 
   //! Maps symbol IDs to type specific IDs
-  vector<int> type_specific_ids;
+  map<int, int> type_specific_ids;
 
   //! Maps type specific IDs of endogenous to symbol IDs
   vector<int> endo_ids;
@@ -204,6 +204,16 @@ public:
     {
     }
   };
+  /* Thrown when requesting the type specific ID of a symbol which doesn’t
+     have one */
+  class NoTypeSpecificIDException
+  {
+  public:
+    const int symb_id;
+    explicit NoTypeSpecificIDException(int symb_id_arg) : symb_id{symb_id_arg}
+    {
+    }
+  };
   //! Thrown when trying to declare a symbol twice
   class AlreadyDeclaredException
   {
@@ -496,7 +506,11 @@ SymbolTable::getTypeSpecificID(int id) const noexcept(false)
 
   validateSymbID(id);
 
-  return type_specific_ids[id];
+  if (auto it = type_specific_ids.find(id);
+      it != type_specific_ids.end())
+    return it->second;
+  else
+    throw NoTypeSpecificIDException(id);
 }
 
 inline int