diff --git a/src/backends/lalr.c b/src/backends/lalr.c
index db9b88ae28caf5d39bf134df454add37577d86c8..ba10e0ca8587c866b72e96d03c1351a9a037d8a2 100644
--- a/src/backends/lalr.c
+++ b/src/backends/lalr.c
@@ -31,18 +31,24 @@ static size_t follow_transition(const HLRTable *table, size_t x, HCFChoice *A)
 {
   HLRAction *action = lrtable_lookup(table, x, A);
   assert(action != NULL);
+
+  // we are interested in a transition out of state x, i.e. a shift action.
+  // while there could also be reduce actions associated with A in state x,
+  // those are not what we are here for. so if action is a conflict, search it
+  // for the shift. there will only be one and it will be the bottom element.
+  if(action->type == HLR_CONFLICT) {
+    HSlistNode *x;
+    for(x=action->branches->head; x; x=x->next) {
+      action = x->elem;
+      assert(action->type != HLR_CONFLICT); // no nesting of conflicts
+      if(action->type == HLR_SHIFT)
+        break;
+    }
+    assert(x != NULL && x->next == NULL);   // shift found at the bottom
+  }
   assert(action->type == HLR_SHIFT);
-  return action->nextstate;
-}
 
-static inline HLRTransition *transition(HArena *arena,
-                                        size_t x, const HCFChoice *A, size_t y)
-{
-  HLRTransition *t = h_arena_malloc(arena, sizeof(HLRTransition));
-  t->from = x;
-  t->symbol = A;
-  t->to = y;
-  return t;
+  return action->nextstate;
 }
 
 // no-op on terminal symbols
@@ -69,8 +75,8 @@ static void transform_productions(const HLRTable *table, HLREnhGrammar *eg,
     HCFChoice **iBj = items;
     for(; *B; B++, iBj++) {
       size_t j = follow_transition(table, i, *B);
-      HLRTransition *i_B_j = transition(arena, i, *B, j);
-      *iBj = h_hashtable_get(eg->tmap, i_B_j);
+      HLRTransition i_B_j = {i, *B, j};
+      *iBj = h_hashtable_get(eg->tmap, &i_B_j);
       assert(*iBj != NULL);
       i = j;
     }
diff --git a/src/t_regression.c b/src/t_regression.c
index 771582cfd835b348e0ed2b4da567ad40fc27800f..7a04bc6e7b89646edc172c50b4078cbd162431d1 100644
--- a/src/t_regression.c
+++ b/src/t_regression.c
@@ -366,6 +366,24 @@ static void test_ast_length_index() {
 }
 #endif // 0
 
+static void test_issue91() {
+  // this ambiguous grammar caused intermittent (?) assertion failures when
+  // trying to compile with the LALR backend:
+  //
+  // assertion "action->type == HLR_SHIFT" failed: file "src/backends/lalr.c",
+  // line 34, function "follow_transition"
+  //
+  // cf. https://gitlab.special-circumstanc.es/hammer/hammer/issues/91
+
+  H_RULE(schar,   h_ch_range(' ', '~'));    /* overlaps digit */
+  H_RULE(digit,   h_ch_range('0', '9'));
+  H_RULE(digits,  h_choice(h_repeat_n(digit, 2), digit, NULL));
+  H_RULE(p,       h_many(h_choice(schar, digits, NULL)));
+
+  int r = h_compile(p, PB_LALR, NULL);
+  g_check_cmp_int(r, ==, -2);
+}
+
 void register_regression_tests(void) {
   g_test_add_func("/core/regression/bug118", test_bug118);
   g_test_add_func("/core/regression/seq_index_path", test_seq_index_path);
@@ -378,4 +396,5 @@ void register_regression_tests(void) {
   g_test_add_func("/core/regression/bug19", test_bug_19);
   g_test_add_func("/core/regression/flatten_null", test_flatten_null);
   //XXX g_test_add_func("/core/regression/ast_length_index", test_ast_length_index);
+  g_test_add_func("/core/regression/issue91", test_issue91);
 }