From df603c72198ffc36887ebfb1ea074e4a94236f5c Mon Sep 17 00:00:00 2001 From: mrhid6 Date: Sun, 26 Jul 2026 18:10:07 +0100 Subject: [PATCH] fix(admin): licence and plan features serialise as [], never null MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Free has no features, so a nil Go slice served "features": null. The portal's type said string[], called .length on it, and took the page down. The guarantee lives on a named Features type with its own MarshalJSON rather than at each of the six places a licence or plan is serialised, because the seventh is the one that would have been forgotten. Applying it at marshal time also fixes rows already holding null in Mongo, which a write-side fix alone would not. Same class, found while checking the rest: staffListInstances built its expiring filter from a nil []string, marshalling to $in: null, which Mongo rejects — so the quiet week when nothing is expiring is precisely when the staff Operations page's own query would have failed. Co-Authored-By: Claude Opus 5 --- license/plans.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/license/plans.go b/license/plans.go index 5d969a2..c4d2197 100644 --- a/license/plans.go +++ b/license/plans.go @@ -22,7 +22,9 @@ var plans = map[string]Plan{ Name: "Free", Deployment: DeploymentCloud, // cloud only, by construction Limits: Limits{MaxServers: 3, MaxSecretGroups: 1, MaxChannels: 1}, - Features: nil, + // Empty rather than nil: nil marshals as JSON null, and this table is + // the seed every plan and licence is cut from. + Features: []string{}, }, TierProfessional: { Tier: TierProfessional,