diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,6 +1,6 @@
 ### 0.24.5
 
-+ Fix an accidental double free for GValues, see (issue 320)[https://github.com/haskell-gi/haskell-gi/issues/320].
++ Fix an accidental double free for GValues, see [issue 320](https://github.com/haskell-gi/haskell-gi/issues/320).
 
 + Accept docsections in gir files, although they are currently ignored. See [issue 318](https://github.com/haskell-gi/haskell-gi/issues/318).
 
diff --git a/haskell-gi.cabal b/haskell-gi.cabal
--- a/haskell-gi.cabal
+++ b/haskell-gi.cabal
@@ -1,5 +1,5 @@
 name:                haskell-gi
-version:             0.24.5
+version:             0.24.6
 synopsis:            Generate Haskell bindings for GObject Introspection capable libraries
 description:         Generate Haskell bindings for GObject Introspection capable libraries. This includes most notably
                      Gtk+, but many other libraries in the GObject ecosystem provide introspection data too.
diff --git a/lib/Data/GI/CodeGen/Callable.hs b/lib/Data/GI/CodeGen/Callable.hs
--- a/lib/Data/GI/CodeGen/Callable.hs
+++ b/lib/Data/GI/CodeGen/Callable.hs
@@ -553,9 +553,16 @@
                     (-1) -> badIntroError $
                             "ScopeTypeNotified without destructor! "
                             <> T.pack (ppShow callable)
-                    k -> let destroyName =
-                               escapedArgName $ (args callable)!!k in
-                           line $ "let " <> destroyName <> " = safeFreeFunPtrPtr"
+                    k -> do
+                      let destroyArg = (args callable)!!k
+                          destroyName = escapedArgName destroyArg
+                      destroyFun <- case argType destroyArg of
+                        TInterface (Name "GLib" "DestroyNotify") ->
+                          return "SP.safeFreeFunPtrPtr"
+                        TInterface (Name "GObject" "ClosureNotify") ->
+                          return "SP.safeFreeFunPtrPtr'"
+                        _ -> notImplementedError $ "Unknown destroy type: " <> tshow (argType destroyArg)
+                      line $ "let " <> destroyName <> " = " <> destroyFun
                 ScopeTypeAsync -> do
                   line $ "let " <> closureName <> " = nullPtr"
                   case argDestroy cb of
diff --git a/lib/Data/GI/CodeGen/Properties.hs b/lib/Data/GI/CodeGen/Properties.hs
--- a/lib/Data/GI/CodeGen/Properties.hs
+++ b/lib/Data/GI/CodeGen/Properties.hs
@@ -33,7 +33,7 @@
 import Data.GI.CodeGen.Type
 import Data.GI.CodeGen.Util
 
-propTypeStr :: Type -> CodeGen Text
+propTypeStr :: Type -> ExcCodeGen Text
 propTypeStr t = case t of
    TBasicType TUTF8 -> return "String"
    TBasicType TFileName -> return "String"
@@ -74,22 +74,22 @@
        APICallback _ -> return "Callback"
        APIStruct s -> if structIsBoxed s
                       then return "Boxed"
-                      else error $ "Unboxed struct property : " ++ show t
+                      else notImplementedError $ "Unboxed struct property : " <> tshow t
        APIUnion u -> if unionIsBoxed u
                      then return "Boxed"
-                     else error $ "Unboxed union property : " ++ show t
+                     else notImplementedError $ "Unboxed union property : " <> tshow t
        APIObject _ -> do
                 isGO <- isGObject t
                 if isGO
                 then return "Object"
-                else error $ "Non-GObject object property : " ++ show t
+                else notImplementedError $ "Non-GObject object property : " <> tshow t
        APIInterface _ -> do
                 isGO <- isGObject t
                 if isGO
                 then return "Object"
-                else error $ "Non-GObject interface property : " ++ show t
-       _ -> error $ "Unknown interface property of type : " ++ show t
-   _ -> error $ "Don't know how to handle properties of type " ++ show t
+                else notImplementedError $ "Non-GObject interface property : " <> tshow t
+       _ -> notImplementedError $ "Unknown interface property of type : " <> tshow t
+   _ -> notImplementedError $ "Don't know how to handle properties of type " <> tshow t
 
 -- | The constraint for setting the given type in properties.
 propSetTypeConstraint :: Type -> CodeGen Text
@@ -180,7 +180,7 @@
     <> " 'Data.GI.Base.Attributes.:=' value ]"
   , "@"]
 
-genPropertySetter :: Text -> Name -> HaddockSection -> Property -> CodeGen ()
+genPropertySetter :: Text -> Name -> HaddockSection -> Property -> ExcCodeGen ()
 genPropertySetter setter n docSection prop = group $ do
   (constraints, t) <- attrType prop
   isNullable <- typeIsNullable (propType prop)
@@ -208,7 +208,7 @@
   , "'Data.GI.Base.Attributes.get' " <> lowerName n <> " #" <> hPropName prop
   , "@"]
 
-genPropertyGetter :: Text -> Name -> HaddockSection -> Property -> CodeGen ()
+genPropertyGetter :: Text -> Name -> HaddockSection -> Property -> ExcCodeGen ()
 genPropertyGetter getter n docSection prop = group $ do
   isNullable <- typeIsNullable (propType prop)
   let isMaybe = isNullable && propReadNullable prop /= Just False
@@ -248,7 +248,7 @@
     "Construct a `GValueConstruct` with valid value for the “@" <> propName prop <> "@” property. This is rarely needed directly, but it is used by `Data.GI.Base.Constructible.new`."
     ]
 
-genPropertyConstructor :: Text -> Name -> HaddockSection -> Property -> CodeGen ()
+genPropertyConstructor :: Text -> Name -> HaddockSection -> Property -> ExcCodeGen ()
 genPropertyConstructor constructor n docSection prop = group $ do
   (constraints, t) <- attrType prop
   tStr <- propTypeStr $ propType prop
@@ -277,7 +277,7 @@
   , "'Data.GI.Base.Attributes.clear'" <> " #" <> hPropName prop
   , "@"]
 
-genPropertyClear :: Text -> Name -> HaddockSection -> Property -> CodeGen ()
+genPropertyClear :: Text -> Name -> HaddockSection -> Property -> ExcCodeGen ()
 genPropertyClear clear n docSection prop = group $ do
   cls <- classConstraint n
   let constraints = ["MonadIO m", cls <> " o"]
