diff --git a/src/lib/parser/mod.rs b/src/lib/parser/mod.rs
index 12ccb77efb4ad04d6ae47820fcf4b759488476e7..b1d7c8b08296c7b606b2f7875474befcd1321688 100644
--- a/src/lib/parser/mod.rs
+++ b/src/lib/parser/mod.rs
@@ -3,7 +3,7 @@ mod loops;
 pub(crate) mod pipelines;
 mod quotes;
 pub(crate) mod shell_expand;
-mod statement;
+pub(crate) mod statement;
 
 pub use self::quotes::Terminator;
 pub(crate) use self::{
diff --git a/src/lib/parser/statement/mod.rs b/src/lib/parser/statement/mod.rs
index 956fb4b9e4fc4826f3f75162187bb8a162dbcbc2..05961150cb8e50521afe672d18ccb590d33d0c2e 100644
--- a/src/lib/parser/statement/mod.rs
+++ b/src/lib/parser/statement/mod.rs
@@ -1,7 +1,7 @@
 mod case;
 mod functions;
 #[cfg(not(fuzzing))]
-mod parse;
+pub mod parse;
 #[cfg(fuzzing)]
 pub mod parse;
 mod splitter;
diff --git a/src/lib/parser/statement/parse.rs b/src/lib/parser/statement/parse.rs
index c1c81114063e0a2a73ffe52b39f594011bac3261..5e31497fe43dbd7069df8894b0cb4dce7566fcaa 100644
--- a/src/lib/parser/statement/parse.rs
+++ b/src/lib/parser/statement/parse.rs
@@ -26,7 +26,13 @@ where
     }
 }
 
-fn is_valid_name(name: &str) -> bool { !name.chars().any(|c| !(c.is_alphanumeric() || c == '_')) }
+pub fn is_valid_name(name: &str) -> bool {
+    if !(name.as_bytes()[0] as char).is_numeric() {
+        !name.chars().any(|c| !(c.is_alphanumeric() || c == '_'))
+    } else {
+        false
+    }
+}
 
 pub(crate) fn parse(code: &str) -> Statement {
     let cmd = code.trim();
diff --git a/src/lib/shell/assignments.rs b/src/lib/shell/assignments.rs
index 3868ef98dc39bb9593b64a189bbe511b85f77cda..ab108096df79b5a37cb470dc24c8b094a5de5c4c 100644
--- a/src/lib/shell/assignments.rs
+++ b/src/lib/shell/assignments.rs
@@ -5,7 +5,7 @@ use super::{
 };
 use crate::{
     lexers::assignments::{Key, Operator, Primitive},
-    parser::assignments::*,
+    parser::{assignments::*, statement::parse::is_valid_name},
     shell::{history::ShellHistory, variables::Value},
     types,
 };
@@ -124,6 +124,10 @@ impl VariableStore for Shell {
                     // sanitize variable names
                     if ["HOME", "HOST", "PWD", "MWD", "SWD", "?"].contains(&key.name) {
                         Err(format!("not allowed to set `{}`", key.name))
+                    } else if !is_valid_name(key.name) {
+                        Err("invalid variable name\nVariable names may only have A-Z, a-z, 0-9 \
+                             and _\nThe first character cannot be a digit"
+                            .into())
                     } else {
                         Ok((key, operator, expression))
                     }