diff --git a/src/language/PugsParser.cpp b/src/language/PugsParser.cpp
index 368e86c834c63935bdc1316e66c9459b96645fe2..58ab42773dd4a0754bf43e8e5cba89d29da5574f 100644
--- a/src/language/PugsParser.cpp
+++ b/src/language/PugsParser.cpp
@@ -102,8 +102,22 @@ parser(const std::string& filename)
     catch (const ParseError& e) {
       const auto p = e.positions().front();
 
+      std::string error_specifier = [] {
+        std::ostringstream os;
+        os << rang::style::bold << "error:" << rang::style::reset << ' ';
+        return os.str();
+      }();
+
+      std::string message = e.what();
+
+      // This is a cosmetic hack to avoid repetition of "error: " in
+      // output
+      if (message.substr(0, error_specifier.size()) == error_specifier) {
+        message = message.substr(error_specifier.size());
+      }
+
       std::cerr << rang::style::bold << p.source << ':' << p.line << ':' << p.column << ": " << rang::style::reset
-                << rang::fgB::red << "error: " << rang::fg::reset << rang::style::bold << e.what() << rang::style::reset
+                << rang::fgB::red << "error: " << rang::fg::reset << rang::style::bold << message << rang::style::reset
                 << '\n'
                 << input.line_at(p) << '\n'
                 << std::string(p.column - 1, ' ') << rang::fgB::yellow << '^' << rang::fg::reset << '\n';