UndefinedExpand { val: String, path: String },
     #[error("undefined call to default.meta: {pattern}\n\tin {path}")]
     UndefinedDefault { pattern: String, path: String },
+    #[error("the parser cannot resolve this input: {input}")]
+    UnreachableRule { input: String },
     #[error(transparent)]
     MetaError(#[from] Box<MetaError>),
     #[error(transparent)]
 
-use crate::{Rule, Scope};
+use crate::{MetaError, Rule, Scope};
+use eyre::Result;
 use pest::iterators::{Pair, Pairs};
 use std::collections::HashMap;
 
-pub fn parse_array_defs(pairs: Pairs<Rule>) -> HashMap<Scope, Vec<String>> {
+pub fn parse_array_defs(pairs: Pairs<Rule>) -> Result<HashMap<Scope, Vec<String>>> {
     let mut map = HashMap::new();
     for pair in pairs {
         if Rule::assign == pair.as_rule() {
-            let (key, val) = parse_assign_array(pair);
+            let (key, val) = parse_assign_array(pair)?;
             map.insert(key, val);
         }
     }
-    map
+    Ok(map)
 }
 
-fn parse_assign_array(pair: Pair<Rule>) -> (Scope, Vec<String>) {
+fn parse_assign_array(pair: Pair<Rule>) -> Result<(Scope, Vec<String>)> {
     let mut key = "";
     let mut val = Vec::default();
     let mut global = true;
             }
             Rule::key => key = pair.as_str(),
             Rule::value => val = parse_array(pair.into_inner()),
-            _ => unreachable!(),
+            _ => {
+                return Err(MetaError::UnreachableRule {
+                    input: pair.to_string(),
+                }
+                .into())
+            }
         }
     }
 
     if global {
-        (Scope::into_global(key), val)
+        Ok((Scope::into_global(key), val))
     } else {
-        (Scope::into_local(key), val)
+        Ok((Scope::into_local(key), val))
     }
 }
 
 
-use crate::{Rule, Scope};
+use crate::{MetaError, Rule, Scope};
+use eyre::Result;
 use pest::iterators::{Pair, Pairs};
 use std::collections::HashMap;
 
-pub fn parse_defs(pairs: Pairs<Rule>) -> HashMap<Scope, String> {
+pub fn parse_defs(pairs: Pairs<Rule>) -> Result<HashMap<Scope, String>> {
     let mut map = HashMap::new();
     for pair in pairs {
         if Rule::assign == pair.as_rule() {
-            let (key, val) = parse_assign(pair);
+            let (key, val) = parse_assign(pair)?;
             map.insert(key, val.to_string());
         }
     }
-    map
+    Ok(map)
 }
 
-fn parse_assign(pair: Pair<Rule>) -> (Scope, &str) {
+fn parse_assign(pair: Pair<Rule>) -> Result<(Scope, &str)> {
     let mut key = "";
     let mut val = "";
     let mut global = true;
                 }
             }
             // nothing else is an acceptable assignment
-            _ => unreachable!(),
+            _ => {
+                return Err(MetaError::UnreachableRule {
+                    input: pair.to_string(),
+                }
+                .into())
+            }
         }
     }
 
     }
 
     if global {
-        (Scope::into_global(key), val)
+        Ok((Scope::into_global(key), val))
     } else {
-        (Scope::into_local(key), val)
+        Ok((Scope::into_local(key), val))
     }
 }