diff --git a/cmd/tailscale/cli/cli.go b/cmd/tailscale/cli/cli.go
index 645859038..b419417f9 100644
--- a/cmd/tailscale/cli/cli.go
+++ b/cmd/tailscale/cli/cli.go
@@ -242,7 +242,7 @@ change in the future.
 }
 
 func nonNilCmds(cmds ...*ffcli.Command) []*ffcli.Command {
-	return slicesx.Filter(cmds[:0], cmds, func(c *ffcli.Command) bool { return c != nil })
+	return slicesx.AppendNonzero(cmds[:0], cmds)
 }
 
 func fatalf(format string, a ...any) {
diff --git a/util/slicesx/slicesx.go b/util/slicesx/slicesx.go
index 1a7e18d91..ff9d47375 100644
--- a/util/slicesx/slicesx.go
+++ b/util/slicesx/slicesx.go
@@ -95,6 +95,17 @@ func Filter[S ~[]T, T any](dst, src S, fn func(T) bool) S {
 	return dst
 }
 
+// AppendNonzero appends all non-zero elements of src to dst.
+func AppendNonzero[S ~[]T, T comparable](dst, src S) S {
+	var zero T
+	for _, v := range src {
+		if v != zero {
+			dst = append(dst, v)
+		}
+	}
+	return dst
+}
+
 // AppendMatching appends elements in ps to dst if f(x) is true.
 func AppendMatching[T any](dst, ps []T, f func(T) bool) []T {
 	for _, p := range ps {
diff --git a/util/slicesx/slicesx_test.go b/util/slicesx/slicesx_test.go
index 597b22b83..346449284 100644
--- a/util/slicesx/slicesx_test.go
+++ b/util/slicesx/slicesx_test.go
@@ -137,6 +137,19 @@ func TestFilterNoAllocations(t *testing.T) {
 	}
 }
 
+func TestAppendNonzero(t *testing.T) {
+	v := []string{"one", "two", "", "four"}
+	got := AppendNonzero(nil, v)
+	want := []string{"one", "two", "four"}
+	if !reflect.DeepEqual(got, want) {
+		t.Errorf("got %v; want %v", got, want)
+	}
+	got = AppendNonzero(v[:0], v)
+	if !reflect.DeepEqual(got, want) {
+		t.Errorf("got %v; want %v", got, want)
+	}
+}
+
 func TestAppendMatching(t *testing.T) {
 	v := []string{"one", "two", "three", "four"}
 	got := AppendMatching(v[:0], v, func(s string) bool { return len(s) > 3 })
diff --git a/util/syspolicy/internal/metrics/metrics.go b/util/syspolicy/internal/metrics/metrics.go
index 0a2aa1192..d8ba271a8 100644
--- a/util/syspolicy/internal/metrics/metrics.go
+++ b/util/syspolicy/internal/metrics/metrics.go
@@ -289,7 +289,7 @@ func newSettingMetric(key setting.Key, scope setting.Scope, suffix string, typ c
 }
 
 func newMetric(nameParts []string, typ clientmetric.Type) metric {
-	name := strings.Join(slicesx.Filter([]string{internal.OS(), "syspolicy"}, nameParts, isNonEmpty), "_")
+	name := strings.Join(slicesx.AppendNonzero([]string{internal.OS(), "syspolicy"}, nameParts), "_")
 	switch {
 	case !ShouldReport():
 		return &funcMetric{name: name, typ: typ}
@@ -304,8 +304,6 @@ func newMetric(nameParts []string, typ clientmetric.Type) metric {
 	}
 }
 
-func isNonEmpty(s string) bool { return s != "" }
-
 func metricScopeName(scope setting.Scope) string {
 	switch scope {
 	case setting.DeviceSetting: