diff --git a/src/client/app/common/scripts/aiscript.ts b/src/client/app/common/scripts/aiscript.ts
index 1c4fe217c3..1e486c455d 100644
--- a/src/client/app/common/scripts/aiscript.ts
+++ b/src/client/app/common/scripts/aiscript.ts
@@ -139,8 +139,12 @@ const envVarsDef = {
 };
 
 class AiScriptError extends Error {
-	constructor(...params) {
-		super(...params);
+	public info?: any;
+
+	constructor(message: string, info?: any) {
+		super(message);
+
+		this.info = info;
 
 		// Maintains proper stack trace for where our error was thrown (only available on V8)
 		if (Error.captureStackTrace) {
@@ -178,7 +182,9 @@ class Scope {
 		}
 
 		throw new AiScriptError(
-			`No such variable '${name}' in scope '${this.name}'`);
+			`No such variable '${name}' in scope '${this.name}'`, {
+				scope: this.layerdStates
+			});
 	}
 }
 
diff --git a/src/client/app/common/scripts/collect-page-vars.ts b/src/client/app/common/scripts/collect-page-vars.ts
index 92727ce6db..683f9b73a5 100644
--- a/src/client/app/common/scripts/collect-page-vars.ts
+++ b/src/client/app/common/scripts/collect-page-vars.ts
@@ -6,25 +6,25 @@ export function collectPageVars(content) {
 				pageVars.push({
 					name: x.name,
 					type: 'string',
-					value: x.default
+					value: x.default || ''
 				});
 			} else if (x.type === 'textareaInput') {
 				pageVars.push({
 					name: x.name,
 					type: 'string',
-					value: x.default
+					value: x.default || ''
 				});
 			} else if (x.type === 'numberInput') {
 				pageVars.push({
 					name: x.name,
 					type: 'number',
-					value: x.default
+					value: x.default || 0
 				});
 			} else if (x.type === 'switch') {
 				pageVars.push({
 					name: x.name,
 					type: 'boolean',
-					value: x.default
+					value: x.default || false
 				});
 			} else if (x.children) {
 				collect(x.children);
diff --git a/src/client/app/common/views/pages/page/page.button.vue b/src/client/app/common/views/pages/page/page.button.vue
index b77d856d5d..3747be96ce 100644
--- a/src/client/app/common/views/pages/page/page.button.vue
+++ b/src/client/app/common/views/pages/page/page.button.vue
@@ -20,13 +20,13 @@ export default Vue.extend({
 	methods: {
 		click() {
 			if (this.value.action === 'dialog') {
-				this.script.reEval();
+				this.script.eval();
 				this.$root.dialog({
 					text: this.script.interpolate(this.value.content)
 				});
 			} else if (this.value.action === 'resetRandom') {
 				this.script.aiScript.updateRandomSeed(Math.random());
-				this.script.reEval();
+				this.script.eval();
 			}
 		}
 	}
diff --git a/src/client/app/common/views/pages/page/page.number-input.vue b/src/client/app/common/views/pages/page/page.number-input.vue
index 51d538c369..31da37330a 100644
--- a/src/client/app/common/views/pages/page/page.number-input.vue
+++ b/src/client/app/common/views/pages/page/page.number-input.vue
@@ -26,7 +26,7 @@ export default Vue.extend({
 	watch: {
 		v() {
 			this.script.aiScript.updatePageVar(this.value.name, this.v);
-			this.script.reEval();
+			this.script.eval();
 		}
 	}
 });
diff --git a/src/client/app/common/views/pages/page/page.switch.vue b/src/client/app/common/views/pages/page/page.switch.vue
index a401e5dfbf..53695f1b36 100644
--- a/src/client/app/common/views/pages/page/page.switch.vue
+++ b/src/client/app/common/views/pages/page/page.switch.vue
@@ -26,7 +26,7 @@ export default Vue.extend({
 	watch: {
 		v() {
 			this.script.aiScript.updatePageVar(this.value.name, this.v);
-			this.script.reEval();
+			this.script.eval();
 		}
 	}
 });
diff --git a/src/client/app/common/views/pages/page/page.text-input.vue b/src/client/app/common/views/pages/page/page.text-input.vue
index 3d659edd5e..cf917dd5a8 100644
--- a/src/client/app/common/views/pages/page/page.text-input.vue
+++ b/src/client/app/common/views/pages/page/page.text-input.vue
@@ -26,7 +26,7 @@ export default Vue.extend({
 	watch: {
 		v() {
 			this.script.aiScript.updatePageVar(this.value.name, this.v);
-			this.script.reEval();
+			this.script.eval();
 		}
 	}
 });
diff --git a/src/client/app/common/views/pages/page/page.textarea-input.vue b/src/client/app/common/views/pages/page/page.textarea-input.vue
index fd8174c273..eece59fefb 100644
--- a/src/client/app/common/views/pages/page/page.textarea-input.vue
+++ b/src/client/app/common/views/pages/page/page.textarea-input.vue
@@ -26,7 +26,7 @@ export default Vue.extend({
 	watch: {
 		v() {
 			this.script.aiScript.updatePageVar(this.value.name, this.v);
-			this.script.reEval();
+			this.script.eval();
 		}
 	}
 });
diff --git a/src/client/app/common/views/pages/page/page.vue b/src/client/app/common/views/pages/page/page.vue
index 27e9a7aec4..5852cb0b82 100644
--- a/src/client/app/common/views/pages/page/page.vue
+++ b/src/client/app/common/views/pages/page/page.vue
@@ -27,15 +27,21 @@ import { url } from '../../../../config';
 
 class Script {
 	public aiScript: AiScript;
+	private onError: any;
 	public vars: Record<string, any>;
 
-	constructor(aiScript) {
+	constructor(aiScript, onError) {
 		this.aiScript = aiScript;
-		this.vars = this.aiScript.evaluateVars();
+		this.onError = onError;
+		this.eval();
 	}
 
-	public reEval() {
-		this.vars = this.aiScript.evaluateVars();
+	public eval() {
+		try {
+			this.vars = this.aiScript.evaluateVars();
+		} catch (e) {
+			this.onError(e);
+		}
 	}
 
 	public interpolate(str: string) {
@@ -86,7 +92,9 @@ export default Vue.extend({
 				visitor: this.$store.state.i,
 				page: page,
 				url: url
-			}));
+			}), e => {
+				console.dir(e);
+			});
 		});
 	},