diff --git a/change-handler.go b/change-handler.go
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..d6e66fcd0d06a074bbfabab8e1438f6c47d58aa2 100644
--- a/change-handler.go
+++ b/change-handler.go
@@ -0,0 +1,50 @@
+// Copyright 2022 schukai GmbH
+// SPDX-License-Identifier: AGPL-3.0
+
+package configuration
+
+import (
+	"github.com/r3labs/diff/v3"
+)
+
+type ChangeEvent struct {
+	Changlog diff.Changelog
+}
+
+type ChangeHook interface {
+	Handle(event ChangeEvent)
+}
+
+// OnChange registers a hook that is called when the configuration changes.
+func (s *Settings[C]) OnChange(hook ChangeHook) *Settings[C] {
+	s.hooks.change = append(s.hooks.change, hook)
+	return s
+}
+
+// HasOnChangeHook returns true if there are registered hooks.
+func (s *Settings[C]) HasOnChangeHook(hook ChangeHook) *Settings[C] {
+	for _, h := range s.hooks.change {
+		if h == hook {
+			break
+		}
+	}
+	return s
+}
+
+// RemoveOnChangeHook removes a change hook from the list of hooks.
+func (s *Settings[C]) RemoveOnChangeHook(hook ChangeHook) *Settings[C] {
+	for i, h := range s.hooks.change {
+		if h == hook {
+			s.hooks.change = append(s.hooks.change[:i], s.hooks.change[i+1:]...)
+			break
+		}
+	}
+	return s
+}
+
+func (s *Settings[C]) notifyChangeHooks(changelog diff.Changelog) *Settings[C] {
+	for _, h := range s.hooks.change {
+		go h.Handle(ChangeEvent{Changlog: changelog})
+	}
+	return s
+}
diff --git a/change.go b/change.go
index cb083d7804b799c6dfd85ade5439a7b893d69643..c3000e42ffdbf355b4462560201707f3ff04bf93 100644
--- a/change.go
+++ b/change.go
@@ -7,48 +7,6 @@ import (
 	"github.com/r3labs/diff/v3"
 )
 
-type ChangeEvent struct {
-	Changlog diff.Changelog
-}
-
-type EventHook interface {
-	Handle(event ChangeEvent)
-}
-
-// OnChange registers a hook that is called when the configuration changes.
-func (s *Settings[C]) OnChange(hook EventHook) *Settings[C] {
-	s.hooks.change = append(s.hooks.change, hook)
-	return s
-}
-
-// HasOnChangeHook returns true if there are registered hooks.
-func (s *Settings[C]) HasOnChangeHook(hook EventHook) *Settings[C] {
-	for _, h := range s.hooks.change {
-		if h == hook {
-			break
-		}
-	}
-	return s
-}
-
-// RemoveOnChangeHook removes a change hook from the list of hooks.
-func (s *Settings[C]) RemoveOnChangeHook(hook EventHook) *Settings[C] {
-	for i, h := range s.hooks.change {
-		if h == hook {
-			s.hooks.change = append(s.hooks.change[:i], s.hooks.change[i+1:]...)
-			break
-		}
-	}
-	return s
-}
-
-func (s *Settings[C]) notifyChangeHooks(changelog diff.Changelog) *Settings[C] {
-	for _, h := range s.hooks.change {
-		h.Handle(ChangeEvent{Changlog: changelog})
-	}
-	return s
-}
-
 func (s *Settings[C]) setConfigInternal(config C, lock bool) *Settings[C] {
 
 	var (
@@ -64,9 +22,12 @@ func (s *Settings[C]) setConfigInternal(config C, lock bool) *Settings[C] {
 		if lock {
 			s.Unlock()
 		}
+	}()
+
+	defer func() {
 
 		if len(changelog) > 0 {
-			go s.notifyChangeHooks(changelog)
+			s.notifyChangeHooks(changelog)
 		}
 
 	}()
diff --git a/change_test.go b/change_test.go
index 0e8616fd12e36b3847e7693bd7b7244d92293536..6dea9f6ff847e7bd7bd13abbf4cf8d9e6f5d268d 100644
--- a/change_test.go
+++ b/change_test.go
@@ -12,7 +12,7 @@ import (
 )
 
 type mockTestEventHandler struct {
-	EventHook
+	ChangeHook
 }
 
 func (m *mockTestEventHandler) Handle(event ChangeEvent) {
@@ -30,7 +30,7 @@ func TestAddRemoveHook(t *testing.T) {
 
 	s := New(config)
 
-	var h EventHook
+	var h ChangeHook
 	h = &mockTestEventHandler{}
 	s.OnChange(h)
 
@@ -60,7 +60,7 @@ func TestReadmeExample(t *testing.T) {
 
 	msg := ""
 
-	var h EventHook
+	var h ChangeHook
 	h = &ChangeEventHandler{
 		Callback: func(event ChangeEvent) {
 			log := event.Changlog
@@ -126,7 +126,7 @@ func TestCangeOnChange(t *testing.T) {
 
 	counter := 0
 
-	var h EventHook
+	var h ChangeHook
 	h = &ChangeEventHandler{
 		Callback: func(event ChangeEvent) {
 			counter++
diff --git a/error-handler.go b/error-handler.go
index 91f3ae462a4f001e9815cf4378e1a53adadfafc0..5eb3752cd00c401595b2de66442a98b12ef7a699 100644
--- a/error-handler.go
+++ b/error-handler.go
@@ -3,28 +3,22 @@
 
 package configuration
 
-import (
-	"fmt"
-	"github.com/r3labs/diff/v3"
-)
-
-type ChangeEvent struct {
-	Changlog diff.Changelog
+type ErrorEvent struct {
 }
 
-type EventHook interface {
-	Handle(event ChangeEvent)
+type ErrorHook interface {
+	Handle(event ErrorEvent)
 }
 
 // OnChange registers a hook that is called when the configuration changes.
-func (s *Settings[C]) OnChange(hook EventHook) *Settings[C] {
-	s.hooks.change = append(s.hooks.change, hook)
+func (s *Settings[C]) OnError(hook ErrorHook) *Settings[C] {
+	s.hooks.error = append(s.hooks.error, hook)
 	return s
 }
 
 // HasOnChangeHook returns true if there are registered hooks.
-func (s *Settings[C]) HasOnChangeHook(hook EventHook) *Settings[C] {
-	for _, h := range s.hooks.change {
+func (s *Settings[C]) HasOnErrorHook(hook ErrorHook) *Settings[C] {
+	for _, h := range s.hooks.error {
 		if h == hook {
 			break
 		}
@@ -33,73 +27,19 @@ func (s *Settings[C]) HasOnChangeHook(hook EventHook) *Settings[C] {
 }
 
 // RemoveOnChangeHook removes a change hook from the list of hooks.
-func (s *Settings[C]) RemoveOnChangeHook(hook EventHook) *Settings[C] {
-	for i, h := range s.hooks.change {
+func (s *Settings[C]) RemoveOnErrorHook(hook ErrorHook) *Settings[C] {
+	for i, h := range s.hooks.error {
 		if h == hook {
-			s.hooks.change = append(s.hooks.change[:i], s.hooks.change[i+1:]...)
+			s.hooks.error = append(s.hooks.error[:i], s.hooks.error[i+1:]...)
 			break
 		}
 	}
 	return s
 }
 
-func (s *Settings[C]) notifyChangeHooks(changelog diff.Changelog) *Settings[C] {
-	for _, h := range s.hooks.change {
-		h.Handle(ChangeEvent{Changlog: changelog})
+func (s *Settings[C]) notifyErrorHooks() *Settings[C] {
+	for _, h := range s.hooks.error {
+		go h.Handle(ErrorEvent{})
 	}
 	return s
 }
-
-func (s *Settings[C]) setConfigInternal(config C, lock bool) *Settings[C] {
-
-	var (
-		changelog diff.Changelog
-		err       error
-	)
-
-	if lock {
-		s.Lock()
-	}
-
-	defer func() {
-		if lock {
-			s.Unlock()
-		}
-
-		if len(changelog) > 0 {
-			go s.notifyChangeHooks(changelog)
-		}
-
-		fmt.Println(">>>>>>>>> setConfigInternal", len(changelog))
-		fmt.Println(changelog)
-		fmt.Println(s.errors)
-
-	}()
-
-	if err := validateConfig[C](config); err != nil {
-		s.errors = append(s.errors, err)
-		return s
-	}
-
-	d, err := diff.NewDiffer()
-	if err != nil {
-		s.errors = append(s.errors, err)
-		return s
-	}
-
-	d.ConvertCompatibleTypes = true
-	d.AllowTypeMismatch = true
-
-	changelog, err = d.Diff(s.config, config)
-	if err != nil {
-		s.errors = append(s.errors, err)
-		return s
-	}
-
-	s.config = config
-	return s
-}
-
-func (s *Settings[C]) SetConfig(config C) *Settings[C] {
-	return s.setConfigInternal(config, true)
-}
diff --git a/error-handler_test.go b/error-handler_test.go
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..96279ff9983f1a18b9dedc8af21769f55201e236 100644
--- a/error-handler_test.go
+++ b/error-handler_test.go
@@ -0,0 +1,68 @@
+package configuration
+
+import (
+	"github.com/stretchr/testify/assert"
+	"testing"
+	"time"
+)
+
+type mockTestEventErrorHandler struct {
+	ErrorHook
+	ch chan bool
+}
+
+func (m *mockTestEventErrorHandler) Handle(event ErrorEvent) {
+	// do nothing
+	m.ch <- true
+
+}
+
+func TestErrorHandling(t *testing.T) {
+
+	defaults := ConfigStruct2{
+		A: "Hello!",
+	}
+
+	c := New(defaults)
+	var h ErrorHook
+	h = &mockTestEventErrorHandler{
+		ch: make(chan bool),
+	}
+
+	c.OnError(h)
+	c.SetDefaultDirectories()
+
+	select {
+	case <-h.(*mockTestEventErrorHandler).ch:
+		assert.True(t, true)
+	case <-time.After(11 * time.Second):
+		t.Error("Timeout, expected error event")
+	}
+
+}
+
+func TestAddRemoveErrorHook(t *testing.T) {
+
+	config := struct {
+		Host string
+	}{
+		Host: "localhost",
+	}
+
+	s := New(config)
+
+	var h ErrorHook
+	h = &mockTestEventErrorHandler{}
+	s.OnError(h)
+
+	if len(s.hooks.error) != 1 {
+		t.Error("Expected 1 got ", len(s.hooks.change))
+	}
+
+	s.RemoveOnErrorHook(h)
+
+	if len(s.hooks.error) != 0 {
+		t.Error("Expected 0 got ", len(s.hooks.change))
+	}
+
+}
diff --git a/export.go b/export.go
index 0c57483150b4a4d704d844a4006abf4f183900bc..e1d9aba2f0fb3252e2f4ac1278de0519b68867d1 100644
--- a/export.go
+++ b/export.go
@@ -50,6 +50,7 @@ func (s *Settings[C]) writeProperties(writer io.Writer) error {
 	p := properties.LoadMap(m)
 
 	_, err := p.Write(writer, properties.UTF8)
+
 	return err
 
 }
@@ -79,6 +80,7 @@ func (s *Settings[C]) WriteFile(fn string, format Format) *Settings[C] {
 
 	defer file.Close()
 	s.Write(io.Writer(file), format)
+
 	return s
 
 }
diff --git a/file.go b/file.go
index 252529e71ad892f1e6e9bfa70a3cda00334d075e..633ac3779c61814dfe6aafce3745e0a53cf3deb4 100644
--- a/file.go
+++ b/file.go
@@ -227,9 +227,6 @@ func (s *Settings[C]) AddUserConfigDirectory() *Settings[C] {
 		return s
 	}
 
-	s.Lock()
-	defer s.Unlock()
-
 	current, err := os.UserConfigDir()
 	if err != nil {
 		s.errors = append(s.errors, err)
diff --git a/handler.go b/handler.go
index eb9becefdb1c1196aee002e15fe9b88f7d144303..20a59e25c443da79f89d0e08e728f9ad01ef5eca 100644
--- a/handler.go
+++ b/handler.go
@@ -7,3 +7,11 @@ type ChangeEventHandler struct {
 func (c *ChangeEventHandler) Handle(event ChangeEvent) {
 	c.Callback(event)
 }
+
+type ErrorEventHandler struct {
+	Callback func(event ErrorEvent)
+}
+
+func (c *ErrorEventHandler) Handle(event ErrorEvent) {
+	c.Callback(event)
+}
diff --git a/http-handler_test.go b/http-handler_test.go
index 61b46f6704ea4a890b865853ea23654c6bca008f..12981d01cbf42f6d8306b7229c742ff4351a35f1 100644
--- a/http-handler_test.go
+++ b/http-handler_test.go
@@ -272,7 +272,7 @@ func TestConfigurationServePostJson(t *testing.T) {
 	closeChan := make(chan bool)
 	counter := 0
 
-	var h EventHook
+	var h ChangeHook
 	h = &ChangeEventHandler{
 		Callback: func(event ChangeEvent) {
 			counter++
diff --git a/import.go b/import.go
index 074a4132819db11f2f0c52f17e859034f3407574..576b508bb2e08b9477f3a253fae6cef0b94e0fa6 100644
--- a/import.go
+++ b/import.go
@@ -6,6 +6,7 @@ package configuration
 import (
 	"bytes"
 	"encoding/json"
+
 	"github.com/imdario/mergo"
 	"github.com/magiconair/properties"
 	"github.com/pelletier/go-toml/v2"
diff --git a/settings.go b/settings.go
index 12d57bdbd1edf116ac65b3bc06e572aab26bacfa..15f66f6a3877f14fd9214e033e99b52c60179f0a 100644
--- a/settings.go
+++ b/settings.go
@@ -28,7 +28,8 @@ type Settings[C any] struct {
 	mnemonic      string
 	importCounter int
 	hooks         struct {
-		change []EventHook
+		change []ChangeHook
+		error  []ErrorHook
 	}
 
 	fileWatch fileWatch
diff --git a/watch_test.go b/watch_test.go
index e796abde5549639452ed32c4ef03674843765740..494970bf736c336d8dfee0437b459cffd451634c 100644
--- a/watch_test.go
+++ b/watch_test.go
@@ -10,6 +10,135 @@ import (
 	"time"
 )
 
+func runTestFilesChange(fn string, data []testHostTimeout, t *testing.T) {
+
+	for _, x := range data {
+
+		h := x.host
+
+		b := []byte("Host: \"" + h + "\"")
+		err := os.WriteFile(fn, b, 0644)
+		if err != nil {
+			t.Error(err)
+			return
+		}
+
+		time.Sleep(x.timeout)
+
+	}
+
+}
+
+func createTestFileForWatch1() (string, error) {
+	f, err := os.CreateTemp("", "watch_test")
+	if err != nil {
+		return "", err
+	}
+
+	f.WriteString("Host: \"127.0.0.1\"")
+	f.Close()
+
+	return f.Name(), nil
+
+}
+
+type testHostTimeout struct {
+	host    string
+	timeout time.Duration
+}
+
+func TestMultiChange(t *testing.T) {
+
+	tmpFn, err := createTestFileForWatch1()
+	if err != nil {
+		t.Error(err)
+		return
+	}
+
+	defer os.Remove(tmpFn)
+
+	config := struct {
+		Host string `yaml:"Host"`
+	}{
+		Host: "localhost",
+	}
+
+	c := New(config)
+	c.SetMnemonic("my-app")
+	assert.Equal(t, c.Config().Host, "localhost")
+
+	result := []string{}
+	signal := make(chan string)
+
+	var h ChangeHook
+	h = &ChangeEventHandler{
+		Callback: func(event ChangeEvent) {
+			result = append(result, event.Changlog[0].To.(string))
+			signal <- event.Changlog[0].To.(string)
+		},
+	}
+
+	var e ErrorHook
+	e = &ErrorEventHandler{
+		Callback: func(event ErrorEvent) {
+			//for _, err := range c.Errors() {
+			//	t.Error(err)
+			//}
+		},
+	}
+
+	c.AddFile(tmpFn, Yaml)
+	c.Import()
+
+	if c.HasErrors() {
+		t.Error(c.Errors())
+	}
+
+	data := []testHostTimeout{
+
+		{
+			host:    "1.org",
+			timeout: time.Millisecond * 100,
+		},
+		{
+			host:    "2.org",
+			timeout: time.Millisecond * 10,
+		},
+		{
+			host:    "3.org",
+			timeout: time.Millisecond * 2,
+		},
+		{
+			host:    "4.org",
+			timeout: time.Millisecond * 100,
+		},
+		{
+			host:    "9.org",
+			timeout: time.Millisecond * 100,
+		},
+	}
+
+	c.OnChange(h).OnError(e).Watch()
+
+	go runTestFilesChange(tmpFn, data, t)
+
+	for loop := true; loop; {
+		select {
+		case <-signal:
+			if len(result) == len(data) {
+				loop = false
+				break
+			}
+		case <-time.After(time.Second * 10):
+			t.Log(result)
+			t.Fatalf("Timeout")
+		}
+	}
+
+	assert.Equal(t, "9.org", c.Config().Host)
+
+}
+
 func TestWatch(t *testing.T) {
 
 	f, err := os.CreateTemp("", "watch_test")
@@ -35,7 +164,7 @@ func TestWatch(t *testing.T) {
 
 	signal := make(chan bool)
 
-	var h EventHook
+	var h ChangeHook
 	h = &ChangeEventHandler{
 		Callback: func(event ChangeEvent) {
 			assert.Equal(t, event.Changlog[0].From, "localhost")