diff --git a/server_apps.go b/server_apps.go
index 7c324c77a681d7565fbe6df8dd7318e8f7d74b1a..bd702c1a20043cce64c73b583959c53a0d07209e 100644
--- a/server_apps.go
+++ b/server_apps.go
@@ -268,10 +268,10 @@ func (s *server) parseAppToml(ctx context.Context, pathInRepo string, obj *objec
 	dec := toml.NewDecoder(reader)
 	err = dec.Decode(&data)
 	if err != nil {
-		return nil, fmt.Errorf("toml decode failed: %w", err)
+		return nil, fmt.Errorf("toml decode (%q) failed: %w", p, err)
 	}
 	if data.App.Name == "" || len(data.App.Name) > 32 {
-		return nil, fmt.Errorf("app name invalif")
+		return nil, fmt.Errorf("app name invalid (must be non-empty and <= 32 chars)")
 	}
 	sections := map[string]bool{
 		"Badge": true,
@@ -279,16 +279,16 @@ func (s *server) parseAppToml(ctx context.Context, pathInRepo string, obj *objec
 		"Music": true,
 	}
 	if !sections[data.App.Menu] {
-		return nil, fmt.Errorf("app menu invalid")
+		return nil, fmt.Errorf("app menu invalid (must be one of 'Badge', 'Apps', 'Music')")
 	}
 	if data.Entry.Class == "" {
 		return nil, fmt.Errorf("no entry class")
 	}
 	if len(data.Metadata.Author) > 32 {
-		return nil, fmt.Errorf("metadata author too long")
+		return nil, fmt.Errorf("metadata author too long (must be <= 32 chars)")
 	}
 	if len(data.Metadata.Description) > 140 {
-		return nil, fmt.Errorf("metadata description too long")
+		return nil, fmt.Errorf("metadata description too long (must be <= 140 chars)")
 	}
 
 	return &appInfo{
@@ -365,11 +365,11 @@ func (s *server) getAppInfo(ctx context.Context, pathInRepo, repo string) (*appI
 	}
 
 	if highsetVerNil {
-		return nil, fmt.Errorf("no version")
+		return nil, fmt.Errorf("no `version` field in `flow3r.toml`")
 	}
 	stars, err := s.getStars(ctx, repo)
 	if err != nil {
-		return nil, fmt.Errorf("getting stars failed: %w", err)
+		return nil, fmt.Errorf("getting gitlab stars failed: %w", err)
 	}
 	app := firstTime[highestVer]
 	app.stars = stars