diff --git a/src/Lib/Script/ScriptStore.cc b/src/Lib/Script/ScriptStore.cc
index af06032f8a5d718425d1dc4aa0563f583091a009..61a970d59026592d3b7d10c4e8222f56ba7185f0 100644
--- a/src/Lib/Script/ScriptStore.cc
+++ b/src/Lib/Script/ScriptStore.cc
@@ -45,31 +45,32 @@ ScriptStore::resetLoadedScripts() noexcept
     luaContext.reset(new Script::LuaContext(streamOut, streamErr));
 }
 
-bool
+std::optional<std::tuple<int, std::string>>
 ScriptStore::executeScript(Uuid id) noexcept
 {
     const auto script = documents.at(id);
     const bool ok     = luaContext->loadDocument(script) == Code::Success;
+    QString errorString;
     std::string buffer;
 
     std::cout << "STDOUT:\n";
     while (std::getline(streamOut, buffer, '\n'))
-        std::cout << buffer << "\n";
+        std::cout << '\t' << buffer << '\n';
 
-    std::cout << "STDERR:\n";
-    while (std::getline(streamErr, buffer, '\n'))
-        std::cout << buffer << "\n";
-
-    if (!ok)
-        std::cout << luaContext->getLastLuaError().toStdString();
-
-    if (luaContext->isFailed()) {
-        std::cout << "LuaContext is in failure mode!!\n";
-        std::cout << luaContext->getFailureDescription() << "\n";
-        return false;
+    if (!ok) {
+        // /home/.../sample-spec.module:31: bad argument #1 to 'export'...
+        std::cout << "STDERR:\n";
+        QRegExp errorDetect(QStringLiteral("^([^\\:]*)\\:(\\d+)\\:(.*)\\n?$"));
+        while (std::getline(streamErr, buffer, '\n')) {
+            std::cout << '\t' << buffer << '\n';
+            if (errorDetect.indexIn(buffer.c_str()) != -1) {
+                std::string errorDesc = errorDetect.cap(3).toStdString();
+                return std::tuple{ QString(errorDetect.cap(2)).toInt(), Utils::trim(errorDesc) };
+            }
+        }
     }
 
-    return ok;
+    return std::nullopt;
 }
 
 const std::vector<std::string_view>
diff --git a/src/Lib/Script/ScriptStore.hh b/src/Lib/Script/ScriptStore.hh
index 76d6e56e0099fb8fe07292049f94c8b09d73aa86..dd4266a998dc370119156b000c1444d8dbc9ad09 100644
--- a/src/Lib/Script/ScriptStore.hh
+++ b/src/Lib/Script/ScriptStore.hh
@@ -3,6 +3,7 @@
 #include "../CRTPStore.hh"
 #include "ScriptDocument.hh"
 #include <sstream>
+#include <optional>
 
 namespace Vivy::Script
 {
@@ -27,7 +28,7 @@ public:
     void resetLoadedScripts() noexcept;
     void loadScriptFolder(const QString &folderPath);
     std::vector<Item> getLoadedScripts() const noexcept;
-    bool executeScript(Uuid) noexcept;
+    std::optional<std::tuple<int, std::string>> executeScript(Uuid) noexcept;
 
     // Get modules from scripts
     const std::vector<std::string_view> getLoadedModules() const noexcept;
diff --git a/src/UI/MainWindow.cc b/src/UI/MainWindow.cc
index 939d3a3cac5e41babefa2ed52c5019c676a9c3ce..b89262cdca7f46e4b925612725a253e312795f72 100644
--- a/src/UI/MainWindow.cc
+++ b/src/UI/MainWindow.cc
@@ -265,8 +265,21 @@ MainWindow::openDocument() noexcept
             (fileType == Utils::DocumentType::Audio) || (fileType == Utils::DocumentType::ASS))
             addTab(new VivyDocumentView(vivyApp->documentStore.loadDocument(filename), documents));
 
-        else if (fileType == Utils::DocumentType::VivyScript)
-            addTab(new ScriptDocumentView(vivyApp->scriptStore.loadDocument(filename), documents));
+        else if (fileType == Utils::DocumentType::VivyScript) {
+            // FIXME: First interpretation of the file to get the error, can do better.
+            std::shared_ptr<ScriptDocument> scriptDocument =
+                vivyApp->scriptStore.loadDocument(filename);
+            std::optional<std::tuple<int, std::string>> errorTuple =
+                vivyApp->scriptStore.executeScript(scriptDocument->getUuid());
+            ScriptDocumentView *newView = new ScriptDocumentView(scriptDocument, documents);
+
+            if (errorTuple.has_value()) {
+                const auto &[line, desc] = errorTuple.value();
+                emit newView->luaErrorFound(line, QString{ desc.c_str() });
+            }
+
+            addTab(newView);
+        }
     } catch (const std::runtime_error &e) {
         qCritical() << "Failed to load document" << filename << "with error:" << e.what();
     }
diff --git a/src/UI/ScriptDocumentView.cc b/src/UI/ScriptDocumentView.cc
index 786dd20365e3d3bc16c4bd16bf71829977d20b84..eea7873654e64e945d79c751c4c5c4673942d2ed 100644
--- a/src/UI/ScriptDocumentView.cc
+++ b/src/UI/ScriptDocumentView.cc
@@ -3,6 +3,7 @@
 #include "ScriptViews/ScriptHighlighter.hh"
 #include "../VivyApplication.hh"
 
+#include <QRegExp>
 #include <QVBoxLayout>
 
 using namespace Vivy;
@@ -21,6 +22,8 @@ ScriptDocumentView::ScriptDocumentView(std::shared_ptr<ScriptDocument> ptr, QWid
     editor->setPlainText(textFile.readAll());
     setCentralWidget(editor);
     editor->setFocus(Qt::OtherFocusReason);
+
+    connect(this, &ScriptDocumentView::luaErrorFound, editor, &ScriptEditor::updateLastLuaError);
 }
 
 void
diff --git a/src/UI/ScriptDocumentView.hh b/src/UI/ScriptDocumentView.hh
index c78c34833d4a2b5d79d9b3657b1fcca745e92632..8e595086bfeae7deba8cf65de2421da827c56eab 100644
--- a/src/UI/ScriptDocumentView.hh
+++ b/src/UI/ScriptDocumentView.hh
@@ -32,10 +32,15 @@ public:
     QIcon getDocumentTabIcon() const noexcept override;
     AbstractDocument *getDocument() const noexcept override;
 
+signals:
+    void luaErrorFound(int, QString);
+
 private:
     ScriptEditor *editor{ nullptr };
     ScriptHighlighter *syntax{ nullptr };
     std::shared_ptr<ScriptDocument> document{ nullptr };
+    QString lastLuaErrorMsg{};
+    int lastLuaErrorLine{ -1 };
 };
 }
 
diff --git a/src/UI/ScriptViews/ScriptEditor.cc b/src/UI/ScriptViews/ScriptEditor.cc
index 362598405bba9536432d40c4373edba5e4ba1d35..7b8a73d94e2231a98f6a4542a6b70fac5d55cabc 100644
--- a/src/UI/ScriptViews/ScriptEditor.cc
+++ b/src/UI/ScriptViews/ScriptEditor.cc
@@ -131,3 +131,9 @@ ScriptEditor::lineNumberAreaPaintEvent(QPaintEvent *event) noexcept
         ++blockNumber;
     }
 }
+
+void
+ScriptEditor::updateLastLuaError(int line, QString desc)
+{
+    qDebug() << "Update error on line" << line << "with description" << desc;
+}
diff --git a/src/UI/ScriptViews/ScriptEditor.hh b/src/UI/ScriptViews/ScriptEditor.hh
index 601a2ed1305420342f0c81f57b35fe9a28c8dc29..01c01769c60d3d324cacb35bb2a55c0684d957d6 100644
--- a/src/UI/ScriptViews/ScriptEditor.hh
+++ b/src/UI/ScriptViews/ScriptEditor.hh
@@ -38,6 +38,9 @@ public:
     void lineNumberAreaPaintEvent(QPaintEvent *event) noexcept;
     int lineNumberAreaWidth() noexcept;
 
+public slots:
+    void updateLastLuaError(int, QString);
+
 protected:
     void resizeEvent(QResizeEvent *event) noexcept override;
     void keyPressEvent(QKeyEvent *e) noexcept override;