From b746b7e55066535fd5f0f29d6c8ee4e089d87fb2 Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:01:58 +0000
Subject: [PATCH 01/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
website/assets/js/pages/try-fleet/sandbox-teleporter.page.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/website/assets/js/pages/try-fleet/sandbox-teleporter.page.js b/website/assets/js/pages/try-fleet/sandbox-teleporter.page.js
index 964af18ca6c..391ad652428 100644
--- a/website/assets/js/pages/try-fleet/sandbox-teleporter.page.js
+++ b/website/assets/js/pages/try-fleet/sandbox-teleporter.page.js
@@ -20,7 +20,7 @@ parasails.registerPage('sandbox-teleporter', {
window.history.replaceState({}, '', '/');
// Binding an event handler to 'onpageshow', if a user navigates to a locally cached version of this page (e.g., A Safari user clicking the back button from their Fleet Sandbox), they will be taken to the fleetdm.com homepage.
- window.onpageshow = function(event) {
+ window.onpageshow = (event) => {
if(event.persisted) {
this.goto('/');
}
From ae86306734eee17e31bb06ef35dd3ea914ea8f8c Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:00 +0000
Subject: [PATCH 02/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
.../AppleMdmPage/components/content/ApplePushCertSetup.tsx | 1 +
1 file changed, 1 insertion(+)
diff --git a/frontend/pages/admin/IntegrationsPage/cards/MdmSettings/AppleMdmPage/components/content/ApplePushCertSetup.tsx b/frontend/pages/admin/IntegrationsPage/cards/MdmSettings/AppleMdmPage/components/content/ApplePushCertSetup.tsx
index 8d52f0238f3..0c0c6e851aa 100644
--- a/frontend/pages/admin/IntegrationsPage/cards/MdmSettings/AppleMdmPage/components/content/ApplePushCertSetup.tsx
+++ b/frontend/pages/admin/IntegrationsPage/cards/MdmSettings/AppleMdmPage/components/content/ApplePushCertSetup.tsx
@@ -29,6 +29,7 @@ const ApplePushCertSetup = ({
try {
await mdmAppleApi.uploadApplePushCertificate(files[0]);
renderFlash("success", "MDM turned on successfully.");
+ setIsUploading(false);
onSetupSuccess();
} catch (e) {
const msg = getErrorReason(e);
From d7f93a9a8ea6f4ec06fadebc0eeb4ace890416e8 Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:01 +0000
Subject: [PATCH 03/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
server/mdm/nanodep/proxy/proxy.go | 2 ++
1 file changed, 2 insertions(+)
diff --git a/server/mdm/nanodep/proxy/proxy.go b/server/mdm/nanodep/proxy/proxy.go
index 1e55289658a..a70145f8898 100644
--- a/server/mdm/nanodep/proxy/proxy.go
+++ b/server/mdm/nanodep/proxy/proxy.go
@@ -79,6 +79,8 @@ func newDirector(store client.ConfigRetriever, logger log.Logger) func(*http.Req
config, err := store.RetrieveConfig(req.Context(), name)
if err != nil {
logger.Info("msg", "retrieve config", "err", err)
+ // do not cache a broken URL derived from a failed config lookup
+ return
}
url, err = url.Parse(config.BaseURL)
if err != nil {
From 7071dbaac6d2ce19b3e0aab5b9dfb0a4625b2d40 Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:02 +0000
Subject: [PATCH 04/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
tools/github-manage/pkg/ghapi/projects.go | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/tools/github-manage/pkg/ghapi/projects.go b/tools/github-manage/pkg/ghapi/projects.go
index 3b2a6cd56a0..ed43c0441ef 100644
--- a/tools/github-manage/pkg/ghapi/projects.go
+++ b/tools/github-manage/pkg/ghapi/projects.go
@@ -58,6 +58,16 @@ func getAliasKeys() []string {
return keys
}
+// escapeGraphQLString escapes backslashes and double quotes so a value can be
+// safely embedded inside a double-quoted GraphQL string literal.
+func escapeGraphQLString(s string) string {
+ s = strings.ReplaceAll(s, `\`, `\\`)
+ s = strings.ReplaceAll(s, `"`, `\"`)
+ s = strings.ReplaceAll(s, "\n", `\n`)
+ s = strings.ReplaceAll(s, "\r", `\r`)
+ return s
+}
+
// ParseJSONtoProjectItems converts JSON data to a slice of ProjectItem structs.
func ParseJSONtoProjectItems(jsonData []byte, limit int) ([]ProjectItem, int, error) {
var items ProjectItemsResponse
@@ -257,7 +267,7 @@ func SetProjectItemFieldValue(itemID string, projectID int, fieldName, value str
// For number fields (like Estimate) - try different possible type names
if field.Type == "NUMBER" || field.Type == "ProjectV2Field" || strings.Contains(strings.ToLower(field.Type), "number") {
command := fmt.Sprintf(`gh api graphql -f query='mutation { updateProjectV2ItemFieldValue(input: { projectId: "%s", itemId: "%s", fieldId: "%s", value: { number: %s } }) { projectV2Item { id } } }'`,
- projectNodeID, itemID, field.ID, value)
+ escapeGraphQLString(projectNodeID), escapeGraphQLString(itemID), escapeGraphQLString(field.ID), escapeGraphQLString(value))
_, err := RunCommandAndReturnOutput(command)
if err != nil {
@@ -288,7 +298,7 @@ func SetProjectItemFieldValue(itemID string, projectID int, fieldName, value str
}
command := fmt.Sprintf(`gh api graphql -f query='mutation { updateProjectV2ItemFieldValue(input: { projectId: "%s", itemId: "%s", fieldId: "%s", value: { singleSelectOptionId: "%s" } }) { projectV2Item { id } } }'`,
- projectNodeID, itemID, field.ID, optionID)
+ escapeGraphQLString(projectNodeID), escapeGraphQLString(itemID), escapeGraphQLString(field.ID), escapeGraphQLString(optionID))
_, err = RunCommandAndReturnOutput(command)
if err != nil {
@@ -313,7 +323,7 @@ func SetProjectItemFieldValue(itemID string, projectID int, fieldName, value str
// Use GraphQL mutation with the actual current iteration ID
command := fmt.Sprintf(`gh api graphql -f query='mutation { updateProjectV2ItemFieldValue(input: { projectId: "%s", itemId: "%s", fieldId: "%s", value: { iterationId: "%s" } }) { projectV2Item { id } } }'`,
- projectNodeID, itemID, field.ID, currentIterationID)
+ escapeGraphQLString(projectNodeID), escapeGraphQLString(itemID), escapeGraphQLString(field.ID), escapeGraphQLString(currentIterationID))
out, err := RunCommandAndReturnOutput(command)
if err != nil {
@@ -332,7 +342,7 @@ func SetProjectItemFieldValue(itemID string, projectID int, fieldName, value str
// For text fields
if field.Type == "TEXT" || strings.Contains(strings.ToLower(field.Type), "text") {
command := fmt.Sprintf(`gh api graphql -f query='mutation { updateProjectV2ItemFieldValue(input: { projectId: "%s", itemId: "%s", fieldId: "%s", value: { text: "%s" } }) { projectV2Item { id } } }'`,
- projectNodeID, itemID, field.ID, value)
+ escapeGraphQLString(projectNodeID), escapeGraphQLString(itemID), escapeGraphQLString(field.ID), escapeGraphQLString(value))
_, err := RunCommandAndReturnOutput(command)
if err != nil {
@@ -344,7 +354,7 @@ func SetProjectItemFieldValue(itemID string, projectID int, fieldName, value str
// If we can't determine the type, try to infer from field name or context
if strings.EqualFold(fieldName, "Estimate") || strings.Contains(strings.ToLower(fieldName), "estimate") {
command := fmt.Sprintf(`gh api graphql -f query='mutation { updateProjectV2ItemFieldValue(input: { projectId: "%s", itemId: "%s", fieldId: "%s", value: { number: %s } }) { projectV2Item { id } } }'`,
- projectNodeID, itemID, field.ID, value)
+ escapeGraphQLString(projectNodeID), escapeGraphQLString(itemID), escapeGraphQLString(field.ID), escapeGraphQLString(value))
_, err := RunCommandAndReturnOutput(command)
if err != nil {
From 8e51aecf43f0346c147601ed5034dda245d98317 Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:03 +0000
Subject: [PATCH 05/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
.../inputs/homebrew/scripts/microsoft_word_uninstall.sh | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/ee/maintained-apps/inputs/homebrew/scripts/microsoft_word_uninstall.sh b/ee/maintained-apps/inputs/homebrew/scripts/microsoft_word_uninstall.sh
index f42f0bf7cb5..fdac953d268 100644
--- a/ee/maintained-apps/inputs/homebrew/scripts/microsoft_word_uninstall.sh
+++ b/ee/maintained-apps/inputs/homebrew/scripts/microsoft_word_uninstall.sh
@@ -134,7 +134,7 @@ remove_receipt_files() {
fi
echo "sudo pkgutil --only-files --files \"$PKGID\" | sed \"s|^|${FULL_INSTALL_LOCATION}/|\" | tr '\\\\n' '\\\\0' | /usr/bin/sudo -u root -E -- /usr/bin/xargs -0 -- /bin/rm -rf"
- sudo pkgutil --only-files --files "$PKGID" | sed "s|^|/${INSTALL_LOCATION}/|" | tr '\n' '\0' | /usr/bin/sudo -u root -E -- /usr/bin/xargs -0 -- /bin/rm -rf
+ sudo pkgutil --only-files --files "$PKGID" | sed "s|^|${FULL_INSTALL_LOCATION}/|" | tr '\n' '\0' | /usr/bin/sudo -u root -E -- /usr/bin/xargs -0 -- /bin/rm -rf
echo "sudo pkgutil --only-dirs --files \"$PKGID\" | sed \"s|^|${FULL_INSTALL_LOCATION}/|\" | grep '\\.app$' | tr '\\\\n' '\\\\0' | /usr/bin/sudo -u root -E -- /usr/bin/xargs -0 -- /bin/rm -rf"
sudo pkgutil --only-dirs --files "$PKGID" | sed "s|^|${FULL_INSTALL_LOCATION}/|" | grep '\.app$' | tr '\n' '\0' | /usr/bin/sudo -u root -E -- /usr/bin/xargs -0 -- /bin/rm -rf
@@ -188,3 +188,4 @@ trash $LOGGED_IN_USER '~/Library/Application Support/CrashReporter/Microsoft Wor
trash $LOGGED_IN_USER '~/Library/Containers/com.microsoft.Word'
trash $LOGGED_IN_USER '~/Library/Preferences/com.microsoft.Word.plist'
trash $LOGGED_IN_USER '~/Library/Saved Application State/com.microsoft.Word.savedState'
+
From 2ae334aaa437d4ed3029b3c6d541b219dfaee1ba Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:05 +0000
Subject: [PATCH 06/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
ee/server/service/scep/sceptest/sceptest.go | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/ee/server/service/scep/sceptest/sceptest.go b/ee/server/service/scep/sceptest/sceptest.go
index 938e14f4482..3012c076bf1 100644
--- a/ee/server/service/scep/sceptest/sceptest.go
+++ b/ee/server/service/scep/sceptest/sceptest.go
@@ -11,7 +11,6 @@ import (
"crypto/x509"
_ "embed"
"encoding/binary"
- "fmt"
"log/slog"
"net/http"
"net/http/httptest"
@@ -151,7 +150,7 @@ func NewTestDynamicChallengeServer(t *testing.T) *httptest.Server {
dynamicChallengeServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
- fmt.Println(r.URL.Path)
+ t.Logf("dynamic challenge request: %s", r.URL.Path)
if _, err := w.Write([]byte("dynamic challenge")); err != nil {
t.Errorf("write dynamic challenge response: %v", err)
}
From bf5d2f261db356d92c4413d5aff2fac34984535e Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:06 +0000
Subject: [PATCH 07/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
frontend/components/InfoBanner/InfoBanner.tsx | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/frontend/components/InfoBanner/InfoBanner.tsx b/frontend/components/InfoBanner/InfoBanner.tsx
index eea024a374b..69a67d03296 100644
--- a/frontend/components/InfoBanner/InfoBanner.tsx
+++ b/frontend/components/InfoBanner/InfoBanner.tsx
@@ -20,7 +20,8 @@ export interface IInfoBannerProps {
cta?: JSX.Element;
/** closable and link are mutually exclusive */
closable?: boolean;
- icon?: IconNames; // TODO: This is unused but several banners have icons within children that can be refactored to use this for consistent styling
+ /** Renders an icon at the start of the banner message */
+ icon?: IconNames;
}
const InfoBanner = ({
@@ -46,6 +47,9 @@ const InfoBanner = ({
const content = (
<>
+ {icon && (
+
+ )}
{children}
{(cta || closable) && (
From 65f637e569bbbe7d9f60ff4f4807cd356bc59db6 Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:07 +0000
Subject: [PATCH 08/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
.../components/MDM/AppleBMTermsMessage/AppleBMTermsMessage.tsx | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/frontend/components/MDM/AppleBMTermsMessage/AppleBMTermsMessage.tsx b/frontend/components/MDM/AppleBMTermsMessage/AppleBMTermsMessage.tsx
index e8d380e36f8..afbd0153588 100644
--- a/frontend/components/MDM/AppleBMTermsMessage/AppleBMTermsMessage.tsx
+++ b/frontend/components/MDM/AppleBMTermsMessage/AppleBMTermsMessage.tsx
@@ -13,7 +13,7 @@ const AppleBMTermsMessage = () => {
cta={
{
};
export default AppleBMTermsMessage;
+
From 16e56a387f8bcbd4888cf0d74d1f16400d32381f Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:08 +0000
Subject: [PATCH 09/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
.../components/AddEntraTenantModal/AddEntraTenantModal.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frontend/pages/admin/IntegrationsPage/cards/MdmSettings/components/AddEntraTenantModal/AddEntraTenantModal.tsx b/frontend/pages/admin/IntegrationsPage/cards/MdmSettings/components/AddEntraTenantModal/AddEntraTenantModal.tsx
index 5932b44e34b..0dfa119cb6a 100644
--- a/frontend/pages/admin/IntegrationsPage/cards/MdmSettings/components/AddEntraTenantModal/AddEntraTenantModal.tsx
+++ b/frontend/pages/admin/IntegrationsPage/cards/MdmSettings/components/AddEntraTenantModal/AddEntraTenantModal.tsx
@@ -46,7 +46,7 @@ const AddEntraTenantModal = ({ onExit }: IAddEntraTenantModalProps) => {
};
const onAddTenant = async () => {
- const { tenantId } = formData;
+ const tenantId = formData.tenantId?.trim().toLowerCase();
const validation = validateFormData({ tenantId });
From 8e504f36ffebd749520e3a7154700b1ab01d6fa6 Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:09 +0000
Subject: [PATCH 10/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
.../components/CommandDetailsModal/CommandDetailsModal.tsx | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/frontend/pages/hosts/components/CommandDetailsModal/CommandDetailsModal.tsx b/frontend/pages/hosts/components/CommandDetailsModal/CommandDetailsModal.tsx
index f3f536283f8..6283a746287 100644
--- a/frontend/pages/hosts/components/CommandDetailsModal/CommandDetailsModal.tsx
+++ b/frontend/pages/hosts/components/CommandDetailsModal/CommandDetailsModal.tsx
@@ -220,8 +220,8 @@ const CommandResultsModal = ({
return {
results: resp.results.map?.((r) => ({
...r,
- payload: atob(r.payload),
- result: atob(r.result),
+ payload: r.payload ? atob(r.payload) : r.payload,
+ result: r.result ? atob(r.result) : r.result,
})),
};
},
@@ -246,3 +246,4 @@ const CommandResultsModal = ({
};
export default CommandResultsModal;
+
From a1e2b262217a86282d44ba5723b74de6cc8ffd6f Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:11 +0000
Subject: [PATCH 11/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
.../components/AddProfileModal/AddProfileModal.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frontend/pages/ManageControlsPage/OSSettings/cards/ConfigurationProfiles/components/ProfileUploader/components/AddProfileModal/AddProfileModal.tsx b/frontend/pages/ManageControlsPage/OSSettings/cards/ConfigurationProfiles/components/ProfileUploader/components/AddProfileModal/AddProfileModal.tsx
index df6e4bcdbad..69bc6c100d0 100644
--- a/frontend/pages/ManageControlsPage/OSSettings/cards/ConfigurationProfiles/components/ProfileUploader/components/AddProfileModal/AddProfileModal.tsx
+++ b/frontend/pages/ManageControlsPage/OSSettings/cards/ConfigurationProfiles/components/ProfileUploader/components/AddProfileModal/AddProfileModal.tsx
@@ -182,11 +182,11 @@ const AddProfileModal = ({
});
renderFlash("success", "Successfully uploaded.");
onUpload();
+ onDone();
} catch (e) {
renderFlash("error", getErrorMessage(e as AxiosResponse));
} finally {
setIsLoading(false);
- onDone();
}
};
From 58732c5ff131aca65142a2d0d9b95779e00381bd Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:12 +0000
Subject: [PATCH 12/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
.../components/BootstrapPackageUploader/helpers.tsx | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/frontend/pages/ManageControlsPage/SetupExperience/cards/BootstrapPackage/components/BootstrapPackageUploader/helpers.tsx b/frontend/pages/ManageControlsPage/SetupExperience/cards/BootstrapPackage/components/BootstrapPackageUploader/helpers.tsx
index de70313206c..56e2dbe79fb 100644
--- a/frontend/pages/ManageControlsPage/SetupExperience/cards/BootstrapPackage/components/BootstrapPackageUploader/helpers.tsx
+++ b/frontend/pages/ManageControlsPage/SetupExperience/cards/BootstrapPackage/components/BootstrapPackageUploader/helpers.tsx
@@ -36,7 +36,7 @@ export const UPLOAD_ERROR_MESSAGES = {
};
export const getErrorMessage = (err: AxiosResponse) => {
- const apiReason = err.data.errors[0].reason;
+ const apiReason = err?.data?.errors?.[0]?.reason ?? "";
const error = Object.values(UPLOAD_ERROR_MESSAGES).find((errType) =>
errType.condition(apiReason)
@@ -48,3 +48,4 @@ export const getErrorMessage = (err: AxiosResponse) => {
return error.message;
};
+
From dd5be6f81c7ef7a318f195720fe8eb5208c6ee95 Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:13 +0000
Subject: [PATCH 13/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
.../FleetMaintainedAppDetailsPage/helpers.tsx | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/frontend/pages/SoftwarePage/SoftwareAddPage/SoftwareFleetMaintained/FleetMaintainedAppDetailsPage/helpers.tsx b/frontend/pages/SoftwarePage/SoftwareAddPage/SoftwareFleetMaintained/FleetMaintainedAppDetailsPage/helpers.tsx
index 61295d1020b..1c10dbdcc61 100644
--- a/frontend/pages/SoftwarePage/SoftwareAddPage/SoftwareFleetMaintained/FleetMaintainedAppDetailsPage/helpers.tsx
+++ b/frontend/pages/SoftwarePage/SoftwareAddPage/SoftwareFleetMaintained/FleetMaintainedAppDetailsPage/helpers.tsx
@@ -53,6 +53,12 @@ export const getFleetAppPolicyQuery = (name: string) => {
return getFleetAppData(name)?.automatic_policy_query;
};
+// NOTE: This logic is duplicated (with minor variations) in
+// SoftwareCustomPackage/helpers.tsx and SoftwareAddPage/helpers.tsx. If you
+// change the timeout detection, the "already available" handling, or the
+// secret-variable handling here, please make the equivalent change in those
+// sibling files as well. TODO: extract a shared base implementation with
+// pluggable extra-branch callbacks so this only needs to be maintained once.
export const getErrorMessage = (err: unknown) => {
const isTimeout =
isAxiosError(err) &&
From 898dfdf9d8fd6db1dab6002c4f20364bdc2040df Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:14 +0000
Subject: [PATCH 14/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
.../pages/SoftwarePage/SoftwareInventory/SoftwareInventory.tsx | 2 ++
1 file changed, 2 insertions(+)
diff --git a/frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventory.tsx b/frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventory.tsx
index 8e2949e608b..d2f5c254c75 100644
--- a/frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventory.tsx
+++ b/frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventory.tsx
@@ -31,6 +31,7 @@ const QUERY_OPTIONS = {
interface ISoftwareInventoryProps {
router: InjectedRouter;
+ location: { pathname: string };
isSoftwareEnabled: boolean;
query: string;
perPage: number;
@@ -44,6 +45,7 @@ interface ISoftwareInventoryProps {
const SoftwareInventory = ({
router,
+ location,
isSoftwareEnabled,
query,
perPage,
From c4f2dddc421baa0324983df8cb5357aa7a5c704b Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:16 +0000
Subject: [PATCH 15/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
.../SoftwareInventoryTable/SoftwareInventoryTable.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventoryTable/SoftwareInventoryTable.tsx b/frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventoryTable/SoftwareInventoryTable.tsx
index 1156aaba7f4..e4d6d442b99 100644
--- a/frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventoryTable/SoftwareInventoryTable.tsx
+++ b/frontend/pages/SoftwarePage/SoftwareInventory/SoftwareInventoryTable/SoftwareInventoryTable.tsx
@@ -156,7 +156,7 @@ const SoftwareTable = ({
let generateTableConfig: ITableConfigGenerator;
if (data === undefined) {
- tableData;
+ tableData = undefined;
generateTableConfig = () => [];
} else if (isSoftwareTitles(data)) {
tableData = data.software_titles;
From e35417b8e8f14b2d91ffbe95877fa5a974010812 Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:17 +0000
Subject: [PATCH 16/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
orbit/cmd/orbit/shell.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/orbit/cmd/orbit/shell.go b/orbit/cmd/orbit/shell.go
index 6fa3ac3aee4..d5b5f43a790 100644
--- a/orbit/cmd/orbit/shell.go
+++ b/orbit/cmd/orbit/shell.go
@@ -155,7 +155,7 @@ var shellCommand = &cli.Command{
// thrift extensions?
pipeName := filepath.Join(c.String("root-dir"), "orbit-osquery.em")
if runtime.GOOS == "windows" {
- pipeName = `\\\\.\\pipe\\orbit-osquery-extension`
+ pipeName = `\\.\pipe\orbit-osquery-extension`
}
registerExtensionRunner(
&g,
From a26583ff1dbbc644af51c6a491f671f41e356b2e Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:18 +0000
Subject: [PATCH 17/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
.../tables/20240829170023_CreateVPPTokenTeamsJoinTable.go | 1 -
1 file changed, 1 deletion(-)
diff --git a/server/datastore/mysql/migrations/tables/20240829170023_CreateVPPTokenTeamsJoinTable.go b/server/datastore/mysql/migrations/tables/20240829170023_CreateVPPTokenTeamsJoinTable.go
index 747e2eea7ed..885f0c0845d 100644
--- a/server/datastore/mysql/migrations/tables/20240829170023_CreateVPPTokenTeamsJoinTable.go
+++ b/server/datastore/mysql/migrations/tables/20240829170023_CreateVPPTokenTeamsJoinTable.go
@@ -10,7 +10,6 @@ func init() {
}
func Up_20240829170023(tx *sql.Tx) error {
- // Idempotent migration.
// Idempotent migration.
_, err := tx.Exec(`
CREATE TABLE IF NOT EXISTS vpp_token_teams (
From 6f8d8607a3de88e453a071f62e9992bc09641044 Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:19 +0000
Subject: [PATCH 18/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
.../tables/20250731151000_EnforceFileVaultAtLogin_test.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/server/datastore/mysql/migrations/tables/20250731151000_EnforceFileVaultAtLogin_test.go b/server/datastore/mysql/migrations/tables/20250731151000_EnforceFileVaultAtLogin_test.go
index c14e3983539..05c284d2a9c 100644
--- a/server/datastore/mysql/migrations/tables/20250731151000_EnforceFileVaultAtLogin_test.go
+++ b/server/datastore/mysql/migrations/tables/20250731151000_EnforceFileVaultAtLogin_test.go
@@ -8,7 +8,7 @@ import (
"github.com/stretchr/testify/require"
)
-func TestUp_20250731151000(t *testing.T) {
+func TestUp_20250723111413(t *testing.T) {
db := applyUpToPrev(t)
stmt := `
From 83bc615271922b6cdf2166688f87046a7e6ef390 Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:20 +0000
Subject: [PATCH 19/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
.../20250904091745_AddCertificateAuthoritiesTable_test.go | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/server/datastore/mysql/migrations/tables/20250904091745_AddCertificateAuthoritiesTable_test.go b/server/datastore/mysql/migrations/tables/20250904091745_AddCertificateAuthoritiesTable_test.go
index 0699797d7a6..27c402b0cc6 100644
--- a/server/datastore/mysql/migrations/tables/20250904091745_AddCertificateAuthoritiesTable_test.go
+++ b/server/datastore/mysql/migrations/tables/20250904091745_AddCertificateAuthoritiesTable_test.go
@@ -135,16 +135,12 @@ func TestUp_20250904091745(t *testing.T) {
`INSERT INTO app_config_json(json_value) VALUES(?) ON DUPLICATE KEY UPDATE json_value = VALUES(json_value)`,
jsonBytes,
)
- if err != nil {
- require.NoError(t, err, "failed to insert app_config_json")
- }
+ require.NoError(t, err, "failed to insert app_config_json")
_, err = db.Exec(
`UPDATE app_config_json SET json_value = JSON_SET(json_value, '$.integrations', CAST(? AS JSON))`,
integrationJSONBytes,
)
- if err != nil {
- require.NoError(t, err, "failed to insert integrations_json into app_config_json")
- }
+ require.NoError(t, err, "failed to insert integrations_json into app_config_json")
// Apply current migration.
applyNext(t, db)
From fb06890b9cf6055eb5ec7105d9e88259e4eeb478 Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:21 +0000
Subject: [PATCH 20/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
server/vulnerabilities/nvd/cve.go | 38 ++++++++++++++++++++++---------
1 file changed, 27 insertions(+), 11 deletions(-)
diff --git a/server/vulnerabilities/nvd/cve.go b/server/vulnerabilities/nvd/cve.go
index f2005718b24..cdd3f54cd81 100644
--- a/server/vulnerabilities/nvd/cve.go
+++ b/server/vulnerabilities/nvd/cve.go
@@ -230,6 +230,19 @@ func TranslateCPEToCVE(
return nil, nil
}
+ // Detect corrupted/empty CVE feed files up front by validating the feed shape/size
+ // directly, rather than inferring corruption from zero downstream vulnerability matches
+ // (which can legitimately happen on well-patched fleets). A feed file is considered
+ // invalid if it is empty (zero bytes) on disk.
+ feedFilesInvalid := false
+ for _, file := range files {
+ info, statErr := os.Stat(file)
+ if statErr != nil || info.Size() == 0 {
+ feedFilesInvalid = true
+ break
+ }
+ }
+
// get all the software CPEs from the database
CPEs, err := ds.ListSoftwareCPEs(ctx)
if err != nil {
@@ -276,9 +289,10 @@ func TranslateCPEToCVE(
// NVD feed file.
softwareVulns := make(map[string]fleet.SoftwareVulnerability)
osVulns := make(map[string]fleet.OSVulnerability)
+ totalCVEsSeen := 0
for _, file := range files {
- foundSoftwareVulns, foundOSVulns, err := checkCVEs(
+ foundSoftwareVulns, foundOSVulns, cveCount, err := checkCVEs(
ctx,
logger,
interfaceParsed,
@@ -288,6 +302,7 @@ func TranslateCPEToCVE(
if err != nil {
return nil, err
}
+ totalCVEsSeen += cveCount
for _, e := range foundSoftwareVulns {
softwareVulns[e.Key()] = e
@@ -322,11 +337,12 @@ func TranslateCPEToCVE(
osInsertErr = true
}
- // Detect corrupted/empty CVE feeds. If we had CPE/OS inputs to match against but produced
- // zero results across every feed file, the feed is almost certainly empty or corrupted
- // (e.g., a failed/corrupted artifact from GitHub) — skip the deletes so we don't wipe
- // legitimate existing software_cve rows that will be re-matched on the next good sync.
- feedProducedNoData := len(allSoftwareVulns) == 0 && len(allOSVulns) == 0
+ // Detect corrupted/empty CVE feeds by validating the feed shape/size directly (empty feed
+ // files on disk, or zero CVE entries parsed across all feed files) instead of inferring
+ // corruption from zero downstream vulnerability matches. Legitimate feeds can produce zero
+ // new vulnerability matches (e.g., on small or well-patched fleets), and that alone should
+ // not prevent stale-vulnerability cleanup.
+ feedProducedNoData := feedFilesInvalid || totalCVEsSeen == 0
// Delete any stale vulnerabilities. A vulnerability is stale iff the last time it was
// updated was more than `2 * periodicity` ago. This assumes that the whole vulnerability
@@ -345,8 +361,8 @@ func TranslateCPEToCVE(
}
}
if feedProducedNoData {
- logger.ErrorContext(ctx, "NVD scan produced no matches with non-empty input; skipping deletes to preserve existing software_cve rows (feed may be corrupted)",
- "software_cpes", len(parsed), "os_cpes", len(cpes), "feed_files", len(files))
+ logger.ErrorContext(ctx, "NVD feed appears empty or corrupted; skipping deletes to preserve existing software_cve rows",
+ "software_cpes", len(parsed), "os_cpes", len(cpes), "feed_files", len(files), "cve_count", totalCVEsSeen)
}
return newVulns, nil
@@ -419,10 +435,10 @@ func checkCVEs(
cpeItems []itemWithNVDMeta,
jsonFile string,
knownNVDBugRules CPEMatchingRules,
-) ([]fleet.SoftwareVulnerability, []fleet.OSVulnerability, error) {
+) ([]fleet.SoftwareVulnerability, []fleet.OSVulnerability, int, error) {
dict, err := cvefeed.LoadJSONDictionary(jsonFile)
if err != nil {
- return nil, nil, err
+ return nil, nil, 0, err
}
// Group dictionary by vendor using a map.
@@ -564,7 +580,7 @@ func checkCVEs(
logger.DebugContext(ctx, "cpes pushed")
wg.Wait()
- return foundSoftwareVulns, foundOSVulns, nil
+ return foundSoftwareVulns, foundOSVulns, len(dict), nil
}
var pythonVersionWithUpdate = regexp.MustCompile(`(alpha|beta|rc)(\d+)`)
From 4e4b4cac78326083fcf16a5465c070f4b36eccdc Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:22 +0000
Subject: [PATCH 21/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
tools/github-manage/cmd/gm/issues_with_historical_label.go | 1 +
1 file changed, 1 insertion(+)
diff --git a/tools/github-manage/cmd/gm/issues_with_historical_label.go b/tools/github-manage/cmd/gm/issues_with_historical_label.go
index 84c2a1397c0..f6d6ff00cca 100644
--- a/tools/github-manage/cmd/gm/issues_with_historical_label.go
+++ b/tools/github-manage/cmd/gm/issues_with_historical_label.go
@@ -46,6 +46,7 @@ var issuesWithHistoricalLabelCmd = &cobra.Command{
issues, err := ghapi.GetIssuesCreatedSinceWithLabel(repo, since, label, verbose, concurrency, olderThan)
if err != nil {
fmt.Fprintf(os.Stderr, "Error fetching issues: %v\n", err)
+ return
}
if len(issues) == 0 {
From 43753f0319feb5f9d495dea06a3c67c1a12478b6 Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:23 +0000
Subject: [PATCH 22/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
tools/github-manage/pkg/ghapi/cache.go | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/tools/github-manage/pkg/ghapi/cache.go b/tools/github-manage/pkg/ghapi/cache.go
index 6b11c1f8918..e16ffef42fc 100644
--- a/tools/github-manage/pkg/ghapi/cache.go
+++ b/tools/github-manage/pkg/ghapi/cache.go
@@ -17,6 +17,7 @@ var (
// MapProjectFieldNameToField caches project field metadata by project ID
MapProjectFieldNameToField = map[int]map[string]ProjectField{}
+ projectFieldsMutex sync.RWMutex
)
// generateProjectItemCacheKey creates a unique key for project item cache.
@@ -42,6 +43,8 @@ func ClearProjectItemIDCache() {
// ClearProjectFieldsCache clears the project fields cache.
func ClearProjectFieldsCache() {
+ projectFieldsMutex.Lock()
+ defer projectFieldsMutex.Unlock()
MapProjectFieldNameToField = make(map[int]map[string]ProjectField)
}
@@ -62,7 +65,9 @@ func GetCacheStats() map[string]interface{} {
projectItemIDCount := len(projectItemIDCache)
projectItemIDMutex.RUnlock()
+ projectFieldsMutex.RLock()
fieldCacheCount := len(MapProjectFieldNameToField)
+ projectFieldsMutex.RUnlock()
return map[string]interface{}{
"project_node_ids": projectNodeIDCount,
@@ -79,3 +84,4 @@ func InvalidateProjectItemID(issueNumber, projectID int) {
defer projectItemIDMutex.Unlock()
delete(projectItemIDCache, cacheKey)
}
+
From c7590c982d05939fae2e3d7dce4b5df84dba18ec Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:25 +0000
Subject: [PATCH 23/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
.../main/java/com/fleetdm/agent/ApiClient.kt | 56 ++++++++++---------
1 file changed, 29 insertions(+), 27 deletions(-)
diff --git a/android/app/src/main/java/com/fleetdm/agent/ApiClient.kt b/android/app/src/main/java/com/fleetdm/agent/ApiClient.kt
index 8f62148f41a..6248ed3ac5b 100644
--- a/android/app/src/main/java/com/fleetdm/agent/ApiClient.kt
+++ b/android/app/src/main/java/com/fleetdm/agent/ApiClient.kt
@@ -257,15 +257,17 @@ object ApiClient : CertificateApiClient {
val result = block()
if (result.isFailure && result.exceptionOrNull() is UnauthorizedException) {
Log.d(TAG, "Received 401, clearing node key and retrying with re-enrollment")
- clearApiKey()
+ enrollmentMutex.withLock {
+ clearApiKey()
+ }
return block()
}
return result
}
- suspend fun enroll(): Result {
+ suspend fun enroll(): Result = enrollmentMutex.withLock {
val credentials = getEnrollmentCredentials()
- credentials ?: return Result.failure(Exception("Credentials not set"))
+ credentials ?: return@withLock Result.failure(Exception("Credentials not set"))
val resp = makeRequest(
endpoint = "/api/fleet/orbit/enroll",
method = "POST",
@@ -286,7 +288,7 @@ object ApiClient : CertificateApiClient {
Log.d(TAG, "Enrollment failed: ${exception.message}")
}
- return resp
+ resp
}
suspend fun getOrbitConfig(): Result = withReenrollOnUnauthorized {
@@ -405,30 +407,29 @@ object ApiClient : CertificateApiClient {
}
private suspend fun getNodeKeyOrEnroll(): Result {
- enrollmentMutex.withLock {
- // Check again inside lock in case another coroutine just enrolled
- val existingKey = getApiKey()
- if (existingKey != null) {
- return Result.success(existingKey)
- }
-
- // Node key is missing, attempt auto-enrollment
- Log.d(TAG, "Orbit node key missing, attempting auto-enrollment")
-
- // Re-enroll
- val enrollResult = enroll()
-
- return enrollResult.fold(
- onSuccess = { response ->
- Log.d(TAG, "Auto-enrollment successful")
- Result.success(response.orbitNodeKey)
- },
- onFailure = { error ->
- FleetLog.e(TAG, "Auto-enrollment failed: ${error.message}")
- Result.failure(error)
- },
- )
+ // Check outside the lock to avoid unnecessary contention when a key already exists.
+ val existingKey = getApiKey()
+ if (existingKey != null) {
+ return Result.success(existingKey)
}
+
+ // Node key is missing, attempt auto-enrollment
+ Log.d(TAG, "Orbit node key missing, attempting auto-enrollment")
+
+ // enroll() acquires enrollmentMutex internally to guard the enroll/store sequence
+ // against concurrent re-enrollment attempts.
+ val enrollResult = enroll()
+
+ return enrollResult.fold(
+ onSuccess = { response ->
+ Log.d(TAG, "Auto-enrollment successful")
+ Result.success(response.orbitNodeKey)
+ },
+ onFailure = { error ->
+ FleetLog.e(TAG, "Auto-enrollment failed: ${error.message}")
+ Result.failure(error)
+ },
+ )
}
private data class EnrollmentCredentials(
@@ -633,3 +634,4 @@ data class GetCertificateTemplateResponse(
*/
fun GetCertificateTemplateResponse.buildScepUrl(serverUrl: String, hostUUID: String): String =
"$serverUrl/mdm/scep/proxy/$hostUUID,g$id,$certificateAuthorityType,${fleetChallenge ?: ""}"
+
From 2bae0f6c7214e1b517adab01ebe82ab128653095 Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:27 +0000
Subject: [PATCH 24/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
android/settings.gradle.kts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/android/settings.gradle.kts b/android/settings.gradle.kts
index 7e677746ee9..a7c431b8678 100644
--- a/android/settings.gradle.kts
+++ b/android/settings.gradle.kts
@@ -19,6 +19,6 @@ dependencyResolutionManagement {
}
}
-rootProject.name = "My Application"
+rootProject.name = "fleetmdm"
include(":app")
-
\ No newline at end of file
+
From 47ed23efee18514f821ac7e159102b6725b2acb3 Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:28 +0000
Subject: [PATCH 25/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
cmd/osquery-perf/osquery_perf/stats.go | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/cmd/osquery-perf/osquery_perf/stats.go b/cmd/osquery-perf/osquery_perf/stats.go
index 05c3157c87a..26beb35c6a4 100644
--- a/cmd/osquery-perf/osquery_perf/stats.go
+++ b/cmd/osquery-perf/osquery_perf/stats.go
@@ -273,10 +273,15 @@ func (s *Stats) Log() {
s.l.Lock()
defer s.l.Unlock()
+ var errorRate float64
+ if s.osqueryEnrollments > 0 {
+ errorRate = float64(s.errors) / float64(s.osqueryEnrollments)
+ }
+
log.Printf(
"uptime: %s, error rate: %.2f, osquery enrolls: %d, orbit enrolls: %d, mdm enrolls: %d, distributed/reads: %d, distributed/writes: %d, config requests: %d, result log requests: %d, mdm sessions initiated: %d, mdm on-demand syncs: %d, mdm commands received: %d, config errors: %d, distributed/read errors: %d, distributed/write errors: %d, log result errors: %d, orbit errors: %d, desktop errors: %d, mdm errors: %d, mdm scep requests: %d, mdm scep success: %d, mdm scep errors: %d, ddm tokens success: %d, ddm tokens errors: %d, ddm declaration items success: %d, ddm declaration items errors: %d, ddm activation success: %d, ddm activation errors: %d, ddm configuration success: %d, ddm configuration errors: %d, ddm status success: %d, ddm status errors: %d, buffered logs: %d, script execs (errs): %d (%d), software installs (errs): %d (%d)",
time.Since(s.StartTime).Round(time.Second),
- float64(s.errors)/float64(s.osqueryEnrollments),
+ errorRate,
s.osqueryEnrollments,
s.orbitEnrollments,
s.mdmEnrollments,
From 5cc6b0f5502d7b0146a98907a8cc6b93af0f99af Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:29 +0000
Subject: [PATCH 26/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
ee/fleetd-chrome/src/tables/os_version.ts | 3 +++
1 file changed, 3 insertions(+)
diff --git a/ee/fleetd-chrome/src/tables/os_version.ts b/ee/fleetd-chrome/src/tables/os_version.ts
index f63b0935605..38d7858383f 100644
--- a/ee/fleetd-chrome/src/tables/os_version.ts
+++ b/ee/fleetd-chrome/src/tables/os_version.ts
@@ -59,6 +59,9 @@ export default class TableOSVersion extends Table {
console.warn(
`Chrome version ${version} does not have expected 4 segments`
);
+ for (const column of ["major", "minor", "build", "patch"]) {
+ warningsArray.push({ column, error_message: "unexpected version format" });
+ }
} else {
[major, minor, build, patch] = splits;
}
From 57aea790132b9b17f0e71dc09a62e57b7fb85d78 Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:30 +0000
Subject: [PATCH 27/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
.../ingesters/homebrew/external_refs/version_shortener.go | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/ee/maintained-apps/ingesters/homebrew/external_refs/version_shortener.go b/ee/maintained-apps/ingesters/homebrew/external_refs/version_shortener.go
index eaf2b8433a5..975a1a45a58 100644
--- a/ee/maintained-apps/ingesters/homebrew/external_refs/version_shortener.go
+++ b/ee/maintained-apps/ingesters/homebrew/external_refs/version_shortener.go
@@ -15,7 +15,7 @@ import (
func makeVersionShortener(keepSegments int) func(*maintained_apps.FMAManifestApp) (*maintained_apps.FMAManifestApp, error) {
return func(app *maintained_apps.FMAManifestApp) (*maintained_apps.FMAManifestApp, error) {
if app.Version == "" {
- return app, fmt.Errorf("empty version for app %s", app.Slug)
+ return app, errors.New(fmt.Sprintf("empty version for app %s", app.Slug))
}
parts := strings.Split(app.Version, ".")
if len(parts) <= keepSegments {
@@ -46,7 +46,7 @@ var (
// the host version always greater, breaking patch policy detection.
func SublimeVersionTransformer(app *maintained_apps.FMAManifestApp) (*maintained_apps.FMAManifestApp, error) {
if app.Version == "" {
- return app, fmt.Errorf("empty version for Sublime app %s", app.Slug)
+ return app, errors.New(fmt.Sprintf("empty version for Sublime app %s", app.Slug))
}
if strings.HasPrefix(app.Version, "Build ") {
return app, nil
From 6b858a9643959bea224dea8c452d2f01ff127851 Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:31 +0000
Subject: [PATCH 28/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
.../inputs/homebrew/scripts/gpg-suite-uninstall.sh | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/ee/maintained-apps/inputs/homebrew/scripts/gpg-suite-uninstall.sh b/ee/maintained-apps/inputs/homebrew/scripts/gpg-suite-uninstall.sh
index e5b6c0a7fea..377d76579c1 100644
--- a/ee/maintained-apps/inputs/homebrew/scripts/gpg-suite-uninstall.sh
+++ b/ee/maintained-apps/inputs/homebrew/scripts/gpg-suite-uninstall.sh
@@ -134,7 +134,7 @@ remove_receipt_files() {
fi
echo "sudo pkgutil --only-files --files \"$PKGID\" | sed \"s|^|${FULL_INSTALL_LOCATION}/|\" | tr '\\\\n' '\\\\0' | /usr/bin/sudo -u root -E -- /usr/bin/xargs -0 -- /bin/rm -rf"
- sudo pkgutil --only-files --files "$PKGID" | sed "s|^|/${INSTALL_LOCATION}/|" | tr '\n' '\0' | /usr/bin/sudo -u root -E -- /usr/bin/xargs -0 -- /bin/rm -rf
+ sudo pkgutil --only-files --files "$PKGID" | sed "s|^|${FULL_INSTALL_LOCATION}/|" | tr '\n' '\0' | /usr/bin/sudo -u root -E -- /usr/bin/xargs -0 -- /bin/rm -rf
echo "sudo pkgutil --only-dirs --files \"$PKGID\" | sed \"s|^|${FULL_INSTALL_LOCATION}/|\" | grep '\\.app$' | tr '\\\\n' '\\\\0' | /usr/bin/sudo -u root -E -- /usr/bin/xargs -0 -- /bin/rm -rf"
sudo pkgutil --only-dirs --files "$PKGID" | sed "s|^|${FULL_INSTALL_LOCATION}/|" | grep '\.app$' | tr '\n' '\0' | /usr/bin/sudo -u root -E -- /usr/bin/xargs -0 -- /bin/rm -rf
@@ -237,3 +237,4 @@ trash $LOGGED_IN_USER '~/Library/PreferencePanes/GPGPreferences.prefPane'
trash $LOGGED_IN_USER '~/Library/Preferences/org.gpgtools.*'
trash $LOGGED_IN_USER '~/Library/Services/GPGServices.service'
+
From ba26d9de34be5358638fa373ff7a21b969f26563 Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:32 +0000
Subject: [PATCH 29/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
ee/server/service/hostidentity/config.go | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/ee/server/service/hostidentity/config.go b/ee/server/service/hostidentity/config.go
index cac57d12281..e4a07125af6 100644
--- a/ee/server/service/hostidentity/config.go
+++ b/ee/server/service/hostidentity/config.go
@@ -9,13 +9,13 @@ import (
"github.com/fleetdm/fleet/v4/server/mdm/scep/depot"
)
-func initAssets(ds fleet.Datastore) error {
+func initAssets(ctx context.Context, ds fleet.Datastore) error {
// Check if we have existing certs and keys
expectedAssets := []fleet.MDMAssetName{
fleet.MDMAssetHostIdentityCACert,
fleet.MDMAssetHostIdentityCAKey,
}
- savedAssets, err := ds.GetAllMDMConfigAssetsByName(context.Background(), expectedAssets, nil)
+ savedAssets, err := ds.GetAllMDMConfigAssetsByName(ctx, expectedAssets, nil)
if err != nil {
// allow not found errors as it means we're generating the assets for the first time.
if !fleet.IsNotFound(err) {
@@ -49,9 +49,10 @@ func initAssets(ds fleet.Datastore) error {
})
}
- if err := ds.InsertMDMConfigAssets(context.Background(), assets, nil); err != nil {
+ if err := ds.InsertMDMConfigAssets(ctx, assets, nil); err != nil {
return fmt.Errorf("inserting host identity SCEP assets: %w", err)
}
}
return nil
}
+
From 5c58cd08b7feb30f81a490400eaa802d5ba4dbd7 Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:33 +0000
Subject: [PATCH 30/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
frontend/components/ActivityItem/ActivityItem.tsx | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/frontend/components/ActivityItem/ActivityItem.tsx b/frontend/components/ActivityItem/ActivityItem.tsx
index bd1ada7694e..42fb33eeadc 100644
--- a/frontend/components/ActivityItem/ActivityItem.tsx
+++ b/frontend/components/ActivityItem/ActivityItem.tsx
@@ -91,11 +91,9 @@ const ActivityItem = ({
? addGravatarUrlToResource({ email: actor_email })
: { gravatar_url: undefined };
- // wrapped just in case the date string does not parse correctly
- let activityCreatedAt: Date;
- try {
- activityCreatedAt = new Date(activity.created_at);
- } catch (e) {
+ // fall back to the current date if the date string does not parse correctly
+ let activityCreatedAt = new Date(activity.created_at);
+ if (isNaN(activityCreatedAt.getTime())) {
activityCreatedAt = new Date();
}
@@ -139,3 +137,4 @@ const ActivityItem = ({
};
export default ActivityItem;
+
From 37ac2635706b15c6aec1adf1e8c6712f1d566ec2 Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:34 +0000
Subject: [PATCH 31/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
.../components/HostPicker.tests.tsx | 21 +++++++------------
1 file changed, 7 insertions(+), 14 deletions(-)
diff --git a/frontend/components/CommandPalette/components/HostPicker.tests.tsx b/frontend/components/CommandPalette/components/HostPicker.tests.tsx
index 4d129009fe9..2f82a937cd9 100644
--- a/frontend/components/CommandPalette/components/HostPicker.tests.tsx
+++ b/frontend/components/CommandPalette/components/HostPicker.tests.tsx
@@ -105,16 +105,15 @@ describe("HostPicker", () => {
team_name: "Engineering",
});
- // The shared QueryClient persists React Query's cache across tests
- // in this file. Earlier tests register an empty result under
- // queryKey ["commandPaletteHosts", ""], so subsequent renders with
- // the same search would read that cached emptiness and never hit
- // the mock. Each column test uses a unique search string to get a
- // fresh queryFn invocation. The mock ignores the query value, so
- // the same `hosts` is returned regardless.
- it("renders a status dot next to the host name (no text)", async () => {
+ // Each test in this file renders with its own fresh QueryClient (see
+ // createCustomRenderer), so there is no cross-test cache to worry
+ // about here. The mock ignores the query value, so the same `hosts`
+ // is returned regardless of the search string used.
+ beforeEach(() => {
mockedHosts.loadHosts.mockResolvedValue(hosts);
+ });
+ it("renders a status dot next to the host name (no text)", async () => {
const { findByText, container } = renderPicker(
);
@@ -131,8 +130,6 @@ describe("HostPicker", () => {
});
it("renders the host's team in the right-aligned column when showTeamColumn", async () => {
- mockedHosts.loadHosts.mockResolvedValue(hosts);
-
const { findByText } = renderPicker(
);
@@ -140,8 +137,6 @@ describe("HostPicker", () => {
});
it("suppresses the team column by default (Free / Primo / single-fleet)", async () => {
- mockedHosts.loadHosts.mockResolvedValue(hosts);
-
const { findByText, queryByText } = renderPicker(
);
@@ -151,8 +146,6 @@ describe("HostPicker", () => {
});
it("highlights the matched substring of the host name", async () => {
- mockedHosts.loadHosts.mockResolvedValue(hosts);
-
const { findByText, container } = renderPicker(
);
From 633a744c1d3cef4db8345a997b7b15ed4b66f011 Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:35 +0000
Subject: [PATCH 32/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
.../CommandPalette/components/PolicyPicker.tests.tsx | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/frontend/components/CommandPalette/components/PolicyPicker.tests.tsx b/frontend/components/CommandPalette/components/PolicyPicker.tests.tsx
index 7fadd277cce..5dddee33614 100644
--- a/frontend/components/CommandPalette/components/PolicyPicker.tests.tsx
+++ b/frontend/components/CommandPalette/components/PolicyPicker.tests.tsx
@@ -158,9 +158,10 @@ describe("PolicyPicker", () => {
});
describe("Patch badge", () => {
- // Unique search values per test sidestep React Query cache pollution
- // from earlier empty-state tests, which registered an empty result
- // under queryKey ["commandPalettePolicies", ..., ""].
+ // Each test uses its own QueryClient (via renderPickerInCommand ->
+ // createCustomRenderer) so results from earlier tests registered under
+ // queryKey ["commandPalettePolicies", ...] cannot leak into these
+ // assertions.
it("renders the Patch badge when policy.type === 'patch'", async () => {
mockedGlobal.loadAllNew.mockResolvedValue({
policies: [
From 27f6b3c668e05f7e7fab6ee39ed3598ccbfdeb2b Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:36 +0000
Subject: [PATCH 33/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
frontend/components/List/List.tests.tsx | 28 +++++++++++++++++++++++--
1 file changed, 26 insertions(+), 2 deletions(-)
diff --git a/frontend/components/List/List.tests.tsx b/frontend/components/List/List.tests.tsx
index afe65046d48..1d6c292ea0b 100644
--- a/frontend/components/List/List.tests.tsx
+++ b/frontend/components/List/List.tests.tsx
@@ -90,7 +90,7 @@ describe("List", () => {
{ customId: "beta", name: "Beta" },
];
- const { container } = render(
+ const { container, rerender } = render(
data={data}
idKey="customId"
@@ -107,7 +107,31 @@ describe("List", () => {
li.textContent?.includes("Beta")
);
- expect(alphaLi?.getAttribute("key")).toBeNull(); // React doesn't expose "key" to the DOM
+ expect(alphaLi).toBeInTheDocument();
expect(betaLi).toBeInTheDocument();
+
+ // Reordering data by customId should reuse the same DOM nodes when idKey
+ // is honored, since React matches elements by their key rather than
+ // position. This verifies idKey drives the keying, not array index.
+ const reorderedData: ICustomItem[] = [data[1], data[0]];
+
+ rerender(
+
+ data={reorderedData}
+ idKey="customId"
+ renderItemRow={(item) => {item.name}}
+ />
+ );
+
+ const reorderedListItems = container.querySelectorAll("li.list__row");
+ const reorderedAlphaLi = Array.from(reorderedListItems).find((li) =>
+ li.textContent?.includes("Alpha")
+ );
+ const reorderedBetaLi = Array.from(reorderedListItems).find((li) =>
+ li.textContent?.includes("Beta")
+ );
+
+ expect(reorderedAlphaLi).toBe(alphaLi);
+ expect(reorderedBetaLi).toBe(betaLi);
});
});
From ca609192223be6259d41034ecee3d81dd8882aad Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:37 +0000
Subject: [PATCH 34/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
.../QuerySidePanel/EventedTableTag/EventedTableTag.tsx | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/frontend/components/side_panels/QuerySidePanel/EventedTableTag/EventedTableTag.tsx b/frontend/components/side_panels/QuerySidePanel/EventedTableTag/EventedTableTag.tsx
index a4b89f366e0..1f78ad8129d 100644
--- a/frontend/components/side_panels/QuerySidePanel/EventedTableTag/EventedTableTag.tsx
+++ b/frontend/components/side_panels/QuerySidePanel/EventedTableTag/EventedTableTag.tsx
@@ -19,7 +19,8 @@ const EventedTableTag = ({ selectedTableName }: IEventedTableTagProps) => {
EVENTED TABLE
@@ -28,3 +29,4 @@ const EventedTableTag = ({ selectedTableName }: IEventedTableTagProps) => {
};
export default EventedTableTag;
+
From 1636a5e936416dafdff1da7168dde85802f966ca Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:38 +0000
Subject: [PATCH 35/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
frontend/components/TableContainer/utilities/config_utils.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frontend/components/TableContainer/utilities/config_utils.ts b/frontend/components/TableContainer/utilities/config_utils.ts
index fed909c7247..a93b6ca2378 100644
--- a/frontend/components/TableContainer/utilities/config_utils.ts
+++ b/frontend/components/TableContainer/utilities/config_utils.ts
@@ -24,7 +24,7 @@ export const getConditionalSelectHeaderCheckboxProps = ({
);
const indeterminate =
!allSelectableRowsSelected &&
- headerProps.rows.some((row) => row.isSelected);
+ headerProps.rows.filter(checkIfRowIsSelectable).some((row) => row.isSelected);
const onChange = () => {
if (checkIfAllSelectableRowsSelected(headerProps.rows)) {
From 6e423b546e5312112aba37be56ffb0c02601c28c Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:40 +0000
Subject: [PATCH 36/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
.../components/TableContainer/utilities/TableContainerUtils.ts | 1 -
1 file changed, 1 deletion(-)
diff --git a/frontend/components/TableContainer/utilities/TableContainerUtils.ts b/frontend/components/TableContainer/utilities/TableContainerUtils.ts
index 2e75ad63577..226749a639c 100644
--- a/frontend/components/TableContainer/utilities/TableContainerUtils.ts
+++ b/frontend/components/TableContainer/utilities/TableContainerUtils.ts
@@ -28,4 +28,3 @@ export const generateResultsCountText = (
return `${resultsCount.toLocaleString()} ${name}`;
};
-export default { generateResultsCountText };
From 30148e4e6f264fe7cc28329a9aebdd1e0a828247 Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:41 +0000
Subject: [PATCH 37/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
.../components/DigicertForm/helpers.ts | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/frontend/pages/admin/IntegrationsPage/cards/CertificateAuthorities/components/DigicertForm/helpers.ts b/frontend/pages/admin/IntegrationsPage/cards/CertificateAuthorities/components/DigicertForm/helpers.ts
index 06832888875..cfeaa70413a 100644
--- a/frontend/pages/admin/IntegrationsPage/cards/CertificateAuthorities/components/DigicertForm/helpers.ts
+++ b/frontend/pages/admin/IntegrationsPage/cards/CertificateAuthorities/components/DigicertForm/helpers.ts
@@ -4,7 +4,14 @@ import valid_url from "components/forms/validators/valid_url";
import { IDigicertFormData } from "./DigicertForm";
-// TODO: create a validator abstraction for this and the other form validation files
+// NOTE: This module intentionally keeps its own generic validation scaffolding
+// (IValidation, IFormValidations, generateFormValidations, getErrorMessage,
+// validateFormData) inline rather than importing a shared abstraction, because
+// no such shared validator utility currently exists in this codebase. A follow-up
+// should extract this scaffolding (duplicated across CustomESTForm, DigicertForm,
+// and likely NDESForm/CustomSCEPForm/HydrantForm/SmallstepForm) into a single
+// generic, reusable form-validation utility to avoid divergent bug fixes across
+// CA form variants.
export interface IDigicertFormValidation {
isValid: boolean;
From ddd7b68c67d310c53c325477950729d4f5e00562 Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:42 +0000
Subject: [PATCH 38/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
.../IntegrationForm/IntegrationForm.tsx | 34 ++++++++++++-------
1 file changed, 22 insertions(+), 12 deletions(-)
diff --git a/frontend/pages/admin/IntegrationsPage/cards/Integrations/components/IntegrationForm/IntegrationForm.tsx b/frontend/pages/admin/IntegrationsPage/cards/Integrations/components/IntegrationForm/IntegrationForm.tsx
index 28616cf8201..8651197c989 100644
--- a/frontend/pages/admin/IntegrationsPage/cards/Integrations/components/IntegrationForm/IntegrationForm.tsx
+++ b/frontend/pages/admin/IntegrationsPage/cards/Integrations/components/IntegrationForm/IntegrationForm.tsx
@@ -107,12 +107,17 @@ const IntegrationForm = ({
integrationEditing.username
) {
// Edit existing jira integration using array replacement
- jiraIntegrationSubmitData.splice(integrationEditing.originalIndex, 1, {
- url,
- username: username || "",
- api_token: apiToken,
- project_key: projectKey || "",
- });
+ jiraIntegrationSubmitData = jiraIntegrationSubmitData.map(
+ (integration, index) =>
+ index === integrationEditing.originalIndex
+ ? {
+ url,
+ username: username || "",
+ api_token: apiToken,
+ project_key: projectKey || "",
+ }
+ : integration
+ );
} else {
// Create new jira integration at end of array
jiraIntegrationSubmitData = [
@@ -134,12 +139,17 @@ const IntegrationForm = ({
integrationEditing.email
) {
// Edit existing zendesk integration using array replacement
- zendeskIntegrationSubmitData.splice(integrationEditing.originalIndex, 1, {
- url,
- email: email || "",
- api_token: apiToken,
- group_id: Number(groupId) || 0,
- });
+ zendeskIntegrationSubmitData = zendeskIntegrationSubmitData.map(
+ (integration, index) =>
+ index === integrationEditing.originalIndex
+ ? {
+ url,
+ email: email || "",
+ api_token: apiToken,
+ group_id: Number(groupId) || 0,
+ }
+ : integration
+ );
} else {
// Create new zendesk integration at end of array
zendeskIntegrationSubmitData = [
From adeb5b08e1c926f435155648786e822fb6fd9218 Mon Sep 17 00:00:00 2001
From: "flamingo[bot]" <277372822+flamingo[bot]@users.noreply.github.com>
Date: Mon, 7 Sep 2026 08:02:43 +0000
Subject: [PATCH 39/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
.../VppPage/components/DeleteVppModal/DeleteVppModal.tsx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/frontend/pages/admin/IntegrationsPage/cards/MdmSettings/VppPage/components/DeleteVppModal/DeleteVppModal.tsx b/frontend/pages/admin/IntegrationsPage/cards/MdmSettings/VppPage/components/DeleteVppModal/DeleteVppModal.tsx
index bb0228ede3b..be072fab4cc 100644
--- a/frontend/pages/admin/IntegrationsPage/cards/MdmSettings/VppPage/components/DeleteVppModal/DeleteVppModal.tsx
+++ b/frontend/pages/admin/IntegrationsPage/cards/MdmSettings/VppPage/components/DeleteVppModal/DeleteVppModal.tsx
@@ -35,9 +35,9 @@ const DeleteVppModal = ({
} catch (e) {
// TODO: Check API sends back correct error messages
renderFlash("error", "Couldn’t delete. Please try again.");
- onCancel();
+ setIsDeleting(false);
}
- }, [onCancel, onDeletedToken, renderFlash, tokenId]);
+ }, [onDeletedToken, renderFlash, tokenId]);
return (
Date: Mon, 7 Sep 2026 08:02:44 +0000
Subject: [PATCH 40/40] fix(adhoc-sweep-fixes): 40 review findings across 40
files
---
.../MdmSettings/VppPage/components/RenewVppModal/helpers.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/frontend/pages/admin/IntegrationsPage/cards/MdmSettings/VppPage/components/RenewVppModal/helpers.ts b/frontend/pages/admin/IntegrationsPage/cards/MdmSettings/VppPage/components/RenewVppModal/helpers.ts
index f7557518992..f40e76182cf 100644
--- a/frontend/pages/admin/IntegrationsPage/cards/MdmSettings/VppPage/components/RenewVppModal/helpers.ts
+++ b/frontend/pages/admin/IntegrationsPage/cards/MdmSettings/VppPage/components/RenewVppModal/helpers.ts
@@ -5,11 +5,11 @@ const DEFAULT_ERROR_MESSAGE = "Couldn’t renew. Please try again.";
// eslint-disable-next-line import/prefer-default-export
export const getErrorMessage = (err: unknown) => {
const invalidTokenReason = getErrorReason(err, {
- reasonIncludes: "invalid",
+ reasonIncludes: "Invalid token",
});
if (invalidTokenReason) {
- return "Invalid token. Please provide a valid token from Apple Business.";
+ return `Invalid token. ${invalidTokenReason}`;
}
return DEFAULT_ERROR_MESSAGE;