diff --git a/vm/opcodes.go b/vm/opcodes.go
index 63b9f8a30..4bc9abf4d 100644
--- a/vm/opcodes.go
+++ b/vm/opcodes.go
@@ -3,7 +3,8 @@ package vm
 type Opcode byte
 
 const (
-	OpPush Opcode = iota
+	OpInvalid Opcode = iota
+	OpPush
 	OpPushInt
 	OpPop
 	OpLoadConst
diff --git a/vm/program.go b/vm/program.go
index 57d7140eb..936eca9a2 100644
--- a/vm/program.go
+++ b/vm/program.go
@@ -73,6 +73,9 @@ func (program *Program) Disassemble() string {
 		}
 
 		switch op {
+		case OpInvalid:
+			code("OpInvalid")
+
 		case OpPush:
 			constant("OpPush")
 
diff --git a/vm/vm.go b/vm/vm.go
index b2b2e619e..ec22c251d 100644
--- a/vm/vm.go
+++ b/vm/vm.go
@@ -93,6 +93,9 @@ func (vm *VM) Run(program *Program, env interface{}) (_ interface{}, err error)
 
 		switch op {
 
+		case OpInvalid:
+			panic("invalid opcode")
+
 		case OpPush:
 			vm.push(program.Constants[arg])
 
diff --git a/vm/vm_test.go b/vm/vm_test.go
index 6e32d4713..a5f24c29a 100644
--- a/vm/vm_test.go
+++ b/vm/vm_test.go
@@ -11,6 +11,7 @@ import (
 	"github.com/antonmedv/expr/checker"
 	"github.com/antonmedv/expr/compiler"
 	"github.com/antonmedv/expr/conf"
+	"github.com/antonmedv/expr/file"
 	"github.com/antonmedv/expr/parser"
 	"github.com/antonmedv/expr/vm"
 	"github.com/stretchr/testify/require"
@@ -380,3 +381,14 @@ func TestRun_TaggedFieldName(t *testing.T) {
 
 	require.Equal(t, "hello world", out)
 }
+
+func TestRun_OpInvalid(t *testing.T) {
+	program := &vm.Program{
+		Locations: []file.Location{{0, 0}},
+		Bytecode:  []vm.Opcode{vm.OpInvalid},
+		Arguments: []int{0},
+	}
+
+	_, err := vm.Run(program, nil)
+	require.EqualError(t, err, "invalid opcode")
+}