improve error handling
diff --git a/gcfg.go b/gcfg.go
index e0b8f8a..4c63cf2 100644
--- a/gcfg.go
+++ b/gcfg.go
@@ -49,7 +49,6 @@
 //  - writing gcfg files
 //  - error handling
 //    - include error context
-//    - avoid reflection-related panics
 //    - more helpful error messages
 //    - error types / codes?
 //    - limit input size?
@@ -110,6 +109,9 @@
 func set(cfg interface{}, sect, sub, name, value string) error {
 	vDest := reflect.ValueOf(cfg).Elem()
 	vSect := fieldFold(vDest, sect)
+	if !vSect.IsValid() {
+		return fmt.Errorf("no corresponding field: section %q", sect)
+	}
 	if vSect.Kind() == reflect.Map {
 		if vSect.IsNil() {
 			vSect.Set(reflect.MakeMap(vSect.Type()))
@@ -123,9 +125,13 @@
 		}
 		vSect = pv.Elem()
 	} else if sub != "" {
-		return fmt.Errorf("expected map; section %q subsection %q", sect, sub)
+		return fmt.Errorf("corresponding field should be a map: "+
+			"section %q subsection %q", sect, sub)
 	}
 	vName := fieldFold(vSect, name)
+	if !vName.IsValid() {
+		return fmt.Errorf("no corresponding field: name %q", name)
+	}
 	vAddr := vName.Addr().Interface()
 	switch v := vAddr.(type) {
 	case *string:
diff --git a/gcfg_test.go b/gcfg_test.go
index 68cdff8..6a7ff5c 100644
--- a/gcfg_test.go
+++ b/gcfg_test.go
@@ -98,13 +98,16 @@
 	{"\n[section]\n=", &conf01{}, false},
 	// error: line too long 
 	{"[section]\nname=value\n" + sp4096, &conf01{}, false},
-	// #50
 	// error: no section
 	{"name=value", &conf01{}, false},
 	// error: failed to parse
 	{"\n[section]\nbool=maybe", &conf02{sect02{}}, false},
 	// error: empty subsection
 	{"\n[sub \"\"]\nname=value", &conf04{}, false},
+	// error: section name not matched
+	{"\n[nonexistent]\nname=value", &conf01{}, false},
+	// error: variable name not matched
+	{"\n[section]\nnonexistent=value", &conf01{}, false},
 }},
 }