diff --git a/lib/oxigraph/src/sparql/error.rs b/lib/oxigraph/src/sparql/error.rs
index 35eba714..94ee6f57 100644
--- a/lib/oxigraph/src/sparql/error.rs
+++ b/lib/oxigraph/src/sparql/error.rs
@@ -6,10 +6,9 @@ use crate::storage::StorageError;
 use std::convert::Infallible;
 use std::error::Error;
 use std::io;
-use thiserror::Error;
 
 /// A SPARQL evaluation error.
-#[derive(Debug, Error)]
+#[derive(Debug, thiserror::Error)]
 #[non_exhaustive]
 pub enum EvaluationError {
     /// An error in SPARQL parsing.
diff --git a/lib/oxigraph/src/storage/error.rs b/lib/oxigraph/src/storage/error.rs
index 1b13bd9b..7a119637 100644
--- a/lib/oxigraph/src/storage/error.rs
+++ b/lib/oxigraph/src/storage/error.rs
@@ -2,10 +2,9 @@ use crate::io::{ParseError, RdfFormat};
 use oxiri::IriParseError;
 use std::error::Error;
 use std::io;
-use thiserror::Error;
 
 /// An error related to storage operations (reads, writes...).
-#[derive(Debug, Error)]
+#[derive(Debug, thiserror::Error)]
 #[non_exhaustive]
 pub enum StorageError {
     /// Error from the OS I/O layer.
@@ -31,7 +30,7 @@ impl From<StorageError> for io::Error {
 }
 
 /// An error return if some content in the database is corrupted.
-#[derive(Debug, Error)]
+#[derive(Debug, thiserror::Error)]
 pub enum CorruptionError {
     #[error("{0}")]
     Msg(String),
@@ -61,7 +60,7 @@ impl From<CorruptionError> for io::Error {
 }
 
 /// An error raised while loading a file into a [`Store`](crate::store::Store).
-#[derive(Debug, Error)]
+#[derive(Debug, thiserror::Error)]
 pub enum LoaderError {
     /// An error raised while reading the file.
     #[error(transparent)]
@@ -94,7 +93,7 @@ impl From<LoaderError> for io::Error {
 }
 
 /// An error raised while writing a file from a [`Store`](crate::store::Store).
-#[derive(Debug, Error)]
+#[derive(Debug, thiserror::Error)]
 pub enum SerializerError {
     /// An error raised while writing the content.
     #[error(transparent)]
diff --git a/lib/oxigraph/src/storage/small_string.rs b/lib/oxigraph/src/storage/small_string.rs
index 0ffa3f3a..355606da 100644
--- a/lib/oxigraph/src/storage/small_string.rs
+++ b/lib/oxigraph/src/storage/small_string.rs
@@ -4,7 +4,6 @@ use std::hash::{Hash, Hasher};
 use std::ops::Deref;
 use std::str::{FromStr, Utf8Error};
 use std::{fmt, str};
-use thiserror::Error;
 
 /// A small inline string
 #[derive(Clone, Copy, Default)]
@@ -169,7 +168,7 @@ impl<'a> TryFrom<&'a str> for SmallString {
     }
 }
 
-#[derive(Debug, Clone, Copy, Error)]
+#[derive(Debug, Clone, Copy, thiserror::Error)]
 pub enum BadSmallStringError {
     #[error("small strings could only contain at most 15 characters, found {0}")]
     TooLong(usize),
diff --git a/lib/oxrdf/src/blank_node.rs b/lib/oxrdf/src/blank_node.rs
index ce07226b..6d565fda 100644
--- a/lib/oxrdf/src/blank_node.rs
+++ b/lib/oxrdf/src/blank_node.rs
@@ -1,5 +1,4 @@
 use rand::random;
-use std::error::Error;
 use std::io::Write;
 use std::{fmt, str};
 
@@ -345,18 +344,10 @@ fn to_integer_id(id: &str) -> Option<u128> {
 }
 
 /// An error raised during [`BlankNode`] IDs validation.
-#[derive(Debug)]
+#[derive(Debug, thiserror::Error)]
+#[error("The blank node identifier is invalid")]
 pub struct BlankNodeIdParseError;
 
-impl fmt::Display for BlankNodeIdParseError {
-    #[inline]
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str("The blank node identifier is invalid")
-    }
-}
-
-impl Error for BlankNodeIdParseError {}
-
 #[cfg(test)]
 mod tests {
     #![allow(clippy::panic_in_result_fn)]
diff --git a/lib/oxrdf/src/parser.rs b/lib/oxrdf/src/parser.rs
index 2d6f1428..f89924f6 100644
--- a/lib/oxrdf/src/parser.rs
+++ b/lib/oxrdf/src/parser.rs
@@ -7,7 +7,6 @@ use crate::{
 use crate::{Subject, Triple};
 use std::char;
 use std::str::{Chars, FromStr};
-use thiserror::Error;
 
 /// This limit is set in order to avoid stack overflow error when parsing nested triples due to too many recursive calls.
 /// The actual limit value is a wet finger compromise between not failing to parse valid files and avoiding to trigger stack overflow errors.
@@ -413,7 +412,7 @@ fn read_hexa_char(input: &mut Chars<'_>, len: usize) -> Result<char, TermParseEr
 }
 
 /// An error raised during term serialization parsing using the [`FromStr`] trait.
-#[derive(Debug, Error)]
+#[derive(Debug, thiserror::Error)]
 pub enum TermParseError {
     #[error("Error while parsing the named node '{value}': {error}")]
     Iri { error: IriParseError, value: String },
diff --git a/lib/oxrdf/src/variable.rs b/lib/oxrdf/src/variable.rs
index 30af6c0f..36dcb3e4 100644
--- a/lib/oxrdf/src/variable.rs
+++ b/lib/oxrdf/src/variable.rs
@@ -1,5 +1,4 @@
 use std::cmp::Ordering;
-use std::error::Error;
 use std::fmt;
 
 /// A [SPARQL query](https://www.w3.org/TR/sparql11-query/) owned variable.
@@ -212,14 +211,6 @@ fn validate_variable_identifier(id: &str) -> Result<(), VariableNameParseError>
 }
 
 /// An error raised during [`Variable`] name validation.
-#[derive(Debug)]
+#[derive(Debug, thiserror::Error)]
+#[error("The variable name is invalid")]
 pub struct VariableNameParseError;
-
-impl fmt::Display for VariableNameParseError {
-    #[inline]
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str("The variable name is invalid")
-    }
-}
-
-impl Error for VariableNameParseError {}
diff --git a/lib/oxrdfio/src/error.rs b/lib/oxrdfio/src/error.rs
index 741ff6d9..ea8fe312 100644
--- a/lib/oxrdfio/src/error.rs
+++ b/lib/oxrdfio/src/error.rs
@@ -1,9 +1,8 @@
 use std::io;
 use std::ops::Range;
-use thiserror::Error;
 
 /// Error returned during RDF format parsing.
-#[derive(Debug, Error)]
+#[derive(Debug, thiserror::Error)]
 pub enum ParseError {
     /// I/O error during parsing (file not found...).
     #[error(transparent)]
@@ -50,7 +49,7 @@ impl From<ParseError> for io::Error {
 }
 
 /// An error in the syntax of the parsed file.
-#[derive(Debug, Error)]
+#[derive(Debug, thiserror::Error)]
 pub enum SyntaxError {
     #[error(transparent)]
     Turtle(#[from] oxttl::SyntaxError),
diff --git a/lib/oxrdfxml/src/error.rs b/lib/oxrdfxml/src/error.rs
index 3ed9312d..1174f09d 100644
--- a/lib/oxrdfxml/src/error.rs
+++ b/lib/oxrdfxml/src/error.rs
@@ -2,10 +2,9 @@ use oxilangtag::LanguageTagParseError;
 use oxiri::IriParseError;
 use std::io;
 use std::sync::Arc;
-use thiserror::Error;
 
 /// Error returned during RDF/XML parsing.
-#[derive(Debug, Error)]
+#[derive(Debug, thiserror::Error)]
 pub enum ParseError {
     /// I/O error during parsing (file not found...).
     #[error(transparent)]
@@ -38,7 +37,7 @@ impl From<quick_xml::Error> for ParseError {
 }
 
 /// An error in the syntax of the parsed file.
-#[derive(Debug, Error)]
+#[derive(Debug, thiserror::Error)]
 pub enum SyntaxError {
     #[error(transparent)]
     Xml(#[from] quick_xml::Error),
diff --git a/lib/oxsdatatypes/src/date_time.rs b/lib/oxsdatatypes/src/date_time.rs
index 0a22473f..0f50f5dc 100644
--- a/lib/oxsdatatypes/src/date_time.rs
+++ b/lib/oxsdatatypes/src/date_time.rs
@@ -6,7 +6,6 @@ use std::error::Error;
 use std::fmt;
 use std::hash::{Hash, Hasher};
 use std::str::FromStr;
-use thiserror::Error;
 
 /// [XML Schema `dateTime` datatype](https://www.w3.org/TR/xmlschema11-2/#dateTime)
 ///
@@ -2040,7 +2039,7 @@ fn time_on_timeline(props: &DateTimeSevenPropertyModel) -> Option<Decimal> {
 }
 
 /// A parsing error
-#[derive(Debug, Clone, Error)]
+#[derive(Debug, Clone, thiserror::Error)]
 pub enum ParseDateTimeError {
     #[error("{day} is not a valid day of {month}")]
     InvalidDayOfMonth { day: u8, month: u8 },
@@ -2402,24 +2401,14 @@ impl Error for DateTimeOverflowError {}
 /// The value provided as timezone is not valid.
 ///
 /// Matches XPath [`FODT0003` error](https://www.w3.org/TR/xpath-functions-31/#ERRFODT0003).
-#[derive(Debug, Clone, Copy)]
+#[derive(Debug, Clone, Copy, thiserror::Error)]
+#[error("invalid timezone offset {}:{}",
+        self.offset_in_minutes / 60,
+        self.offset_in_minutes.abs() % 60)]
 pub struct InvalidTimezoneError {
     offset_in_minutes: i64,
 }
 
-impl fmt::Display for InvalidTimezoneError {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(
-            f,
-            "invalid timezone offset {}:{}",
-            self.offset_in_minutes / 60,
-            self.offset_in_minutes.abs() % 60
-        )
-    }
-}
-
-impl Error for InvalidTimezoneError {}
-
 #[cfg(test)]
 mod tests {
     #![allow(clippy::panic_in_result_fn)]
diff --git a/lib/oxsdatatypes/src/decimal.rs b/lib/oxsdatatypes/src/decimal.rs
index 63f1c357..8005800d 100644
--- a/lib/oxsdatatypes/src/decimal.rs
+++ b/lib/oxsdatatypes/src/decimal.rs
@@ -3,7 +3,6 @@ use std::error::Error;
 use std::fmt;
 use std::fmt::Write;
 use std::str::FromStr;
-use thiserror::Error;
 
 const DECIMAL_PART_DIGITS: u32 = 18;
 const DECIMAL_PART_POW: i128 = 1_000_000_000_000_000_000;
@@ -610,7 +609,7 @@ impl fmt::Display for Decimal {
 }
 
 /// An error when parsing a [`Decimal`].
-#[derive(Debug, Clone, Error)]
+#[derive(Debug, Clone, thiserror::Error)]
 pub enum ParseDecimalError {
     #[error("Value overflow")]
     Overflow,
diff --git a/lib/oxsdatatypes/src/duration.rs b/lib/oxsdatatypes/src/duration.rs
index 35f00bce..fe0514ab 100644
--- a/lib/oxsdatatypes/src/duration.rs
+++ b/lib/oxsdatatypes/src/duration.rs
@@ -1,6 +1,5 @@
 use crate::{DateTime, Decimal};
 use std::cmp::Ordering;
-use std::error::Error;
 use std::fmt;
 use std::str::FromStr;
 use std::time::Duration as StdDuration;
@@ -937,7 +936,8 @@ fn decimal_prefix(input: &str) -> (&str, &str) {
 }
 
 /// A parsing error
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, thiserror::Error)]
+#[error("{msg}")]
 pub struct ParseDurationError {
     msg: &'static str,
 }
@@ -946,46 +946,24 @@ const OVERFLOW_ERROR: ParseDurationError = ParseDurationError {
     msg: "Overflow error",
 };
 
-impl fmt::Display for ParseDurationError {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(self.msg)
-    }
-}
-
 impl ParseDurationError {
     const fn msg(msg: &'static str) -> Self {
         Self { msg }
     }
 }
 
-impl Error for ParseDurationError {}
-
 /// An overflow during [`Duration`]-related operations.
 ///
 /// Matches XPath [`FODT0002` error](https://www.w3.org/TR/xpath-functions-31/#ERRFODT0002).
-#[derive(Debug, Clone, Copy)]
+#[derive(Debug, Clone, Copy, thiserror::Error)]
+#[error("overflow during xsd:duration computation")]
 pub struct DurationOverflowError;
 
-impl fmt::Display for DurationOverflowError {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str("overflow during xsd:duration computation")
-    }
-}
-
-impl Error for DurationOverflowError {}
-
 /// The year-month and the day-time components of a [`Duration`] have an opposite sign.
-#[derive(Debug, Clone, Copy)]
+#[derive(Debug, Clone, Copy, thiserror::Error)]
+#[error("The xsd:yearMonthDuration and xsd:dayTimeDuration components of a xsd:duration can't have opposite sign")]
 pub struct OppositeSignInDurationComponentsError;
 
-impl fmt::Display for OppositeSignInDurationComponentsError {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str("The xsd:yearMonthDuration and xsd:dayTimeDuration components of a xsd:duration can't have opposite sign")
-    }
-}
-
-impl Error for OppositeSignInDurationComponentsError {}
-
 impl From<OppositeSignInDurationComponentsError> for ParseDurationError {
     #[inline]
     fn from(_: OppositeSignInDurationComponentsError) -> Self {
@@ -1000,6 +978,7 @@ mod tests {
     #![allow(clippy::panic_in_result_fn)]
 
     use super::*;
+    use std::error::Error;
 
     #[test]
     fn from_str() -> Result<(), ParseDurationError> {
diff --git a/lib/oxttl/src/toolkit/error.rs b/lib/oxttl/src/toolkit/error.rs
index a90de168..33f2a916 100644
--- a/lib/oxttl/src/toolkit/error.rs
+++ b/lib/oxttl/src/toolkit/error.rs
@@ -1,7 +1,5 @@
-use std::error::Error;
 use std::ops::Range;
 use std::{fmt, io};
-use thiserror::Error;
 
 /// A position in a text i.e. a `line` number starting from 0, a `column` number starting from 0 (in number of code points) and a global file `offset` starting from 0 (in number of bytes).
 #[derive(Eq, PartialEq, Debug, Clone, Copy)]
@@ -14,7 +12,7 @@ pub struct TextPosition {
 /// An error in the syntax of the parsed file.
 ///
 /// It is composed of a message and a byte range in the input.
-#[derive(Debug)]
+#[derive(Debug, thiserror::Error)]
 pub struct SyntaxError {
     pub(super) location: Range<TextPosition>,
     pub(super) message: String,
@@ -68,8 +66,6 @@ impl fmt::Display for SyntaxError {
     }
 }
 
-impl Error for SyntaxError {}
-
 impl From<SyntaxError> for io::Error {
     #[inline]
     fn from(error: SyntaxError) -> Self {
@@ -80,7 +76,7 @@ impl From<SyntaxError> for io::Error {
 /// A parsing error.
 ///
 /// It is the union of [`SyntaxError`] and [`io::Error`].
-#[derive(Debug, Error)]
+#[derive(Debug, thiserror::Error)]
 pub enum ParseError {
     /// I/O error during parsing (file not found...).
     #[error(transparent)]
diff --git a/lib/sparesults/src/error.rs b/lib/sparesults/src/error.rs
index 31c55ea2..4b1e4342 100644
--- a/lib/sparesults/src/error.rs
+++ b/lib/sparesults/src/error.rs
@@ -2,10 +2,9 @@ use oxrdf::TermParseError;
 use std::io;
 use std::ops::Range;
 use std::sync::Arc;
-use thiserror::Error;
 
 /// Error returned during SPARQL result formats format parsing.
-#[derive(Debug, Error)]
+#[derive(Debug, thiserror::Error)]
 pub enum ParseError {
     /// I/O error during parsing (file not found...).
     #[error(transparent)]
@@ -47,7 +46,7 @@ impl From<quick_xml::Error> for ParseError {
 }
 
 /// An error in the syntax of the parsed file.
-#[derive(Debug, Error)]
+#[derive(Debug, thiserror::Error)]
 pub enum SyntaxError {
     #[error(transparent)]
     Json(#[from] json_event_parser::SyntaxError),
diff --git a/lib/spargebra/src/parser.rs b/lib/spargebra/src/parser.rs
index ff67818d..ecd980a4 100644
--- a/lib/spargebra/src/parser.rs
+++ b/lib/spargebra/src/parser.rs
@@ -13,7 +13,6 @@ use std::char;
 use std::collections::{HashMap, HashSet};
 use std::mem::take;
 use std::str::FromStr;
-use thiserror::Error;
 
 /// Parses a SPARQL query with an optional base IRI to resolve relative IRIs in the query.
 pub fn parse_query(query: &str, base_iri: Option<&str>) -> Result<Query, ParseError> {
@@ -32,7 +31,7 @@ pub fn parse_update(update: &str, base_iri: Option<&str>) -> Result<Update, Pars
 }
 
 /// Error returned during SPARQL parsing.
-#[derive(Debug, Error)]
+#[derive(Debug, thiserror::Error)]
 pub enum ParseError {
     #[error("Invalid SPARQL base IRI provided: {0}")]
     InvalidBaseIri(#[from] IriParseError),