Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
d5e7014
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
1f82791
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
a0d56cd
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
ff0b47d
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
2463fcd
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
c6e2def
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
acd0731
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
5335150
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
fcdaab5
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
6673a95
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
1760faa
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
d920560
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
ba91e79
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
91674c0
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
b9aadb5
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
b365257
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
18c146b
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
82a5c80
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
1b685f5
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
dbee11f
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
0b2a2e6
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
356f11a
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
e052e2f
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
30c44cb
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
4514078
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
db7c7c2
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
ef66c59
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
fb22509
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
3053cc2
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
be69b81
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
0f8ade8
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
22150ca
fix(FLEETMDM-002-2): 37 review findings across 32 files
flamingo[bot] Aug 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions cmd/cve/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ func downloadLatestGitHubAsset(dbDir, fileName string) error {
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
return fmt.Errorf("get last mod start date: %w", fmt.Errorf("unexpected status code %d", resp.StatusCode))
return fmt.Errorf("unexpected status code %d fetching %s", resp.StatusCode, fileName)
}

lastModStartDate, err := io.ReadAll(resp.Body)
Comment on lines 153 to 159

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 downloadLatestGitHubAsset double-wraps the same error context redundantly

In downloadLatestGitHubAsset, the status-code error branch no longer wraps with the redundant "get last mod start date: %w" prefix (which duplicated the same context already applied to the client.Get error). It now returns fmt.Errorf("unexpected status code %d fetching %s", resp.StatusCode, fileName) directly, exactly matching the suggested fix, eliminating the doubled message.

πŸ€– Prompt for AI agents
In cmd/cve/generate.go around line 145, review and complete this code-review fix: downloadLatestGitHubAsset double-wraps the same error context redundantly.
What the draft fix changed: In `downloadLatestGitHubAsset`, the status-code error branch no longer wraps with the redundant `"get last mod start date: %w"` prefix (which duplicated the same context already applied to the `client.Get` error). It now returns `fmt.Errorf("unexpected status code %d fetching %s", resp.StatusCode, fileName)` directly, exactly matching the suggested fix, eliminating the doubled message.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 90 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand Down Expand Up @@ -271,11 +271,26 @@ func gunzipFileToDisk(filename, dbpath string) error {

// Using a maxBytes limit to prevent decompression bombs: gosec G110
maxBytes := 200 * 1024 * 1024 // 200MB
_, err = io.CopyN(out, gz, int64(maxBytes))
written, err := io.CopyN(out, gz, int64(maxBytes))
if err != nil && err != io.EOF {
msg := fmt.Sprintf("error copying file %s: %v", f.Name(), err)
panic(msg)
}
if written == int64(maxBytes) {
// Check if there is more data beyond the limit, which means the file
// exceeds maxBytes and was not fully copied; fail rather than silently
// truncate.
extra := make([]byte, 1)
n, peekErr := gz.Read(extra)
if n > 0 {
msg := fmt.Sprintf("error copying file %s: exceeds maximum allowed size of %d bytes", f.Name(), maxBytes)
panic(msg)
}
if peekErr != nil && peekErr != io.EOF {
msg := fmt.Sprintf("error copying file %s: %v", f.Name(), peekErr)
panic(msg)
}
}

return nil
}
Comment on lines 271 to 296

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 io.CopyN uses a fixed 200MB cap but silently truncates larger files instead of failing the decompression-bomb guard

In gunzipFileToDisk, after io.CopyN copies up to maxBytes, the code now checks whether exactly maxBytes were written and, if so, attempts to read one more byte from gz to detect leftover data; if any extra byte is present it panics with an "exceeds maximum allowed size" message instead of silently truncating. This addresses the described truncation defect using only the existing panic-based error-handling style in this file. Risk/incompleteness: this is a heuristic boundary check (exact edge case where the true file size is exactly maxBytes will not trigger a false positive, but it adds an extra Read call on the gzip stream which should be safe since gz is not touched again afterward); a more thorough fix might instead stream in a loop with an explicit running counter and bail out immediately upon exceeding the limit rather than after a full CopyN, but that would be a larger structural change beyond the minimal fix requested.

πŸ€– Prompt for AI agents
In cmd/cve/generate.go around line 254, review and complete this code-review fix: io.CopyN uses a fixed 200MB cap but silently truncates larger files instead of failing the decompression-bomb guard.
What the draft fix changed: In `gunzipFileToDisk`, after `io.CopyN` copies up to `maxBytes`, the code now checks whether exactly `maxBytes` were written and, if so, attempts to read one more byte from `gz` to detect leftover data; if any extra byte is present it panics with an "exceeds maximum allowed size" message instead of silently truncating. This addresses the described truncation defect using only the existing panic-based error-handling style in this file. Risk/incompleteness: this is a heuristic boundary check (exact edge case where the true file size is exactly `maxBytes` will not trigger a false positive, but it adds an extra `Read` call on the gzip stream which should be safe since `gz` is not touched again afterward); a more thorough fix might instead stream in a loop with an explicit running counter and bail out immediately upon exceeding the limit rather than after a full `CopyN`, but that would be a larger structural change beyond the minimal fix requested.
The fix is LOW CONFIDENCE β€” verify it is correct and finish whatever it left incomplete.

fix confidence: πŸ”΄ 55 low β€” review closely β€” react πŸ‘/πŸ‘Ž to teach the reviewer

3 changes: 2 additions & 1 deletion orbit/cmd/desktop/desktop_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ func blockWaitForStopEvent(_ string) error {
func trayIconExists() bool {
conn, err := dbus.SessionBus()
if err != nil {
log.Error().Err(err)
log.Error().Err(err).Msg("trayIconExists: connect to session bus")
return false
}

// Get the name we would expect systray to reserve for our tray icon.
Comment on lines 54 to 61

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 dbus SessionBus error is logged but not returned/wrapped, then execution continues with a nil/invalid conn

In trayIconExists() (orbit/cmd/desktop/desktop_linux.go), added return false immediately after logging the dbus.SessionBus() error, and added a .Msg("trayIconExists: connect to session bus") to the log call, preventing the subsequent call to conn.Names() on a nil/invalid connection.

πŸ€– Prompt for AI agents
In orbit/cmd/desktop/desktop_linux.go around line 53, review and complete this code-review fix: dbus SessionBus error is logged but not returned/wrapped, then execution continues with a nil/invalid conn.
What the draft fix changed: In trayIconExists() (orbit/cmd/desktop/desktop_linux.go), added `return false` immediately after logging the dbus.SessionBus() error, and added a `.Msg("trayIconExists: connect to session bus")` to the log call, preventing the subsequent call to conn.Names() on a nil/invalid connection.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 95 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand Down
4 changes: 2 additions & 2 deletions orbit/pkg/platform/platform_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ func GetProcessesByName(name string) ([]*gopsutil_process.Process, error) {

// sanity check on returned snapshot handle
if snapshot == windows.InvalidHandle {
return nil, errors.New("the snapshot returned returned by CreateToolhelp32Snapshot is invalid")
return nil, errors.New("the snapshot returned by CreateToolhelp32Snapshot is invalid")
}
// Closing the handle to avoid handle leaks.
defer windows.CloseHandle(snapshot) //nolint:errcheck
Comment on lines 163 to 169

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 πŸ”΅ Duplicated word 'returned returned' in error message

In GetProcessesByName, fixed the duplicated word in the error string from "the snapshot returned returned by CreateToolhelp32Snapshot is invalid" to "the snapshot returned by CreateToolhelp32Snapshot is invalid".

πŸ€– Prompt for AI agents
In orbit/pkg/platform/platform_windows.go around line 172, review and complete this code-review fix: Duplicated word 'returned returned' in error message.
What the draft fix changed: In `GetProcessesByName`, fixed the duplicated word in the error string from `"the snapshot returned returned by CreateToolhelp32Snapshot is invalid"` to `"the snapshot returned by CreateToolhelp32Snapshot is invalid"`.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 95 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand Down Expand Up @@ -322,7 +322,7 @@ func hardwareGetSMBiosUUID() (string, error) {
// UUID sanity check
isValidUUID, err := isValidUUID(uuidBytes)
if err != nil {
return "", fmt.Errorf("%v", err)
return "", fmt.Errorf("%w", err)
}

if !isValidUUID {
Comment on lines 322 to 328

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 fmt.Errorf wrapping error already includes the underlying error via %v inside a generic wrapper, losing %w chain

In hardwareGetSMBiosUUID (orbit/pkg/platform/platform_windows.go), changed return "", fmt.Errorf("%v", err) to return "", fmt.Errorf("%w", err) after the isValidUUID call, preserving the error chain for errors.Is/errors.As.

πŸ€– Prompt for AI agents
In orbit/pkg/platform/platform_windows.go around line 253, review and complete this code-review fix: fmt.Errorf wrapping error already includes the underlying error via %v inside a generic wrapper, losing %w chain.
What the draft fix changed: In `hardwareGetSMBiosUUID` (orbit/pkg/platform/platform_windows.go), changed `return "", fmt.Errorf("%v", err)` to `return "", fmt.Errorf("%w", err)` after the `isValidUUID` call, preserving the error chain for `errors.Is`/`errors.As`.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 90 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand Down
2 changes: 1 addition & 1 deletion orbit/pkg/token/readwriter.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ func (rw *ReadWriter) SetRemoteUpdateFunc(f remoteUpdaterFunc) {
func (rw *ReadWriter) Write(id string) error {
if rw.remoteUpdate != nil {
if err := rw.remoteUpdate(id); err != nil {
return err
return fmt.Errorf("remote update of token: %w", err)
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 os.WriteFile error in orbit token ReadWriter.Write is wrapped but remoteUpdate error is not

In ReadWriter.Write, changed return err to return fmt.Errorf("remote update of token: %w", err) for the rw.remoteUpdate(id) error path, aligning it with the wrapping convention used by all other error returns in the function.

πŸ€– Prompt for AI agents
In orbit/pkg/token/readwriter.go around line 96, review and complete this code-review fix: os.WriteFile error in orbit token ReadWriter.Write is wrapped but remoteUpdate error is not.
What the draft fix changed: In `ReadWriter.Write`, changed `return err` to `return fmt.Errorf("remote update of token: %w", err)` for the `rw.remoteUpdate(id)` error path, aligning it with the wrapping convention used by all other error returns in the function.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 95 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

}

Expand Down
2 changes: 1 addition & 1 deletion orbit/pkg/update/flag_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ func (r *ExtensionRunner) Run(config *fleet.OrbitConfig) error {
}
return nil
default:
return fmt.Errorf("stat file: %s", extensionAutoLoadFile)
return fmt.Errorf("stat file %s: %w", extensionAutoLoadFile, err)
}
}

Comment on lines 152 to 158

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 readFlagFile call-site wraps errors, but writeFlagFile bare-passes underlying WriteFile error without additional context beyond function name repeat

In ExtensionRunner.Run (default branch of the switch stat, err := os.Stat(...) statement in DoExtensionConfigUpdate), changed return fmt.Errorf("stat file: %s", extensionAutoLoadFile) to return fmt.Errorf("stat file %s: %w", extensionAutoLoadFile, err), wrapping the underlying os.Stat error with %w so the causal chain is preserved, consistent with other call sites in the file.

πŸ€– Prompt for AI agents
In orbit/pkg/update/flag_runner.go around line 140, review and complete this code-review fix: readFlagFile call-site wraps errors, but writeFlagFile bare-passes underlying WriteFile error without additional context beyond function name repeat.
What the draft fix changed: In `ExtensionRunner.Run` (default branch of the `switch stat, err := os.Stat(...)` statement in `DoExtensionConfigUpdate`), changed `return fmt.Errorf("stat file: %s", extensionAutoLoadFile)` to `return fmt.Errorf("stat file %s: %w", extensionAutoLoadFile, err)`, wrapping the underlying `os.Stat` error with `%w` so the causal chain is preserved, consistent with other call sites in the file.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 95 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand Down
5 changes: 4 additions & 1 deletion orbit/pkg/update/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,10 @@ func (r *Runner) updateTarget(target string) error {
}

func (r *Runner) Interrupt(err error) {
r.cancel <- struct{}{}
select {
case r.cancel <- struct{}{}:
default:
}
}

// compareVersion compares the old and new versions of a binary and prints the appropriate message.
Comment on lines 372 to 381

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 Interrupt() drops potential panic on closed/full cancel channel without any guard

Changed Interrupt in orbit/pkg/update/runner.go to use a non-blocking select with default when sending to r.cancel, exactly as suggested, preventing a permanent block on repeated calls after the channel's buffer (capacity 1) is already full or after Execute() has already consumed/returned.

(Automatically downgraded: no change in this fix lands near this finding's line β€” verify whether it was actually addressed.)

πŸ€– Prompt for AI agents
In orbit/pkg/update/runner.go around line 315, review and complete this code-review fix: Interrupt() drops potential panic on closed/full cancel channel without any guard.
What the draft fix changed: Changed `Interrupt` in orbit/pkg/update/runner.go to use a non-blocking `select` with `default` when sending to `r.cancel`, exactly as suggested, preventing a permanent block on repeated calls after the channel's buffer (capacity 1) is already full or after `Execute()` has already consumed/returned.

_(Automatically downgraded: no change in this fix lands near this finding's line β€” verify whether it was actually addressed.)_
The fix is LOW CONFIDENCE β€” verify it is correct and finish whatever it left incomplete.

fix confidence: πŸ”΄ 40 low β€” review closely β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ CREATE TABLE IF NOT EXISTS host_mdm_apple_declarations (
)
`)
if err != nil {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 Migration error creating host_mdm_apple_declarations table has a typo but is otherwise correctly wrapped

In Up_20240327115530, fixed the typo in the error message for the host_mdm_apple_declarations table creation: changed "creatign host_mdm_apple_declarations table %w" to "creating host_mdm_apple_declarations table: %w", matching the wrapping style used by the other error messages in the same function.

πŸ€– Prompt for AI agents
In server/datastore/mysql/migrations/tables/20240327115530_AddDDMTables.go around line 127, review and complete this code-review fix: Migration error creating host_mdm_apple_declarations table has a typo but is otherwise correctly wrapped.
What the draft fix changed: In `Up_20240327115530`, fixed the typo in the error message for the host_mdm_apple_declarations table creation: changed "creatign host_mdm_apple_declarations table %w" to "creating host_mdm_apple_declarations table: %w", matching the wrapping style used by the other error messages in the same function.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 95 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

return fmt.Errorf("creatign host_mdm_apple_declarations table %w", err)
return fmt.Errorf("creating host_mdm_apple_declarations table: %w", err)
}

return nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ func Up_20240815000001(tx *sql.Tx) error {
// Idempotent migration.
if !columnExists(tx, "vpp_apps_teams", "self_service") {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 Non-lowercase, inconsistent error message wrapping in migration

Changed the capitalized error wrap message "Failed to add self_service to vpp_apps_teams: %w" to lowercase "failed to add self_service to vpp_apps_teams: %w" in the Up_20240815000001 function, matching the established lowercase error message convention used by sibling migrations.

πŸ€– Prompt for AI agents
In server/datastore/mysql/migrations/tables/20240815000001_AddSelfServiceToVPPAppsTeams.go around line 14, review and complete this code-review fix: Non-lowercase, inconsistent error message wrapping in migration.
What the draft fix changed: Changed the capitalized error wrap message "Failed to add self_service to vpp_apps_teams: %w" to lowercase "failed to add self_service to vpp_apps_teams: %w" in the Up_20240815000001 function, matching the established lowercase error message convention used by sibling migrations.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 95 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

if _, err := tx.Exec("ALTER TABLE vpp_apps_teams ADD COLUMN self_service bool NOT NULL DEFAULT false"); err != nil {
return fmt.Errorf("Failed to add self_service to vpp_apps_teams: %w", err)
return fmt.Errorf("failed to add self_service to vpp_apps_teams: %w", err)
}
}
return nil
Expand All @@ -22,3 +22,4 @@ func Up_20240815000001(tx *sql.Tx) error {
func Down_20240815000001(tx *sql.Tx) error {
return nil
}

Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func Up_20250304162702(tx *sql.Tx) error {
UNIQUE KEY idx_ca_config_assets_name (name)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci`)
if err != nil {
return fmt.Errorf("failed to create ca_config_assets table: %s", err)
return fmt.Errorf("failed to create ca_config_assets table: %w", err)
}

if !columnExists(tx, "host_mdm_managed_certificates", "not_valid_after") {
Comment on lines 22 to 28

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 Error wrapped with %s instead of %w loses the error chain in AddCATables migration

Changed both fmt.Errorf calls in Up_20250304162702 from %s to %w for the wrapped err (the "failed to create ca_config_assets table" and "failed to add not_valid_after column to host_mdm_managed_certificates table" error messages), preserving the error chain for errors.Is/errors.As, consistent with sibling migrations.

πŸ€– Prompt for AI agents
In server/datastore/mysql/migrations/tables/20250304162702_AddCATables.go around line 21, review and complete this code-review fix: Error wrapped with %s instead of %w loses the error chain in AddCATables migration.
What the draft fix changed: Changed both `fmt.Errorf` calls in `Up_20250304162702` from `%s` to `%w` for the wrapped `err` (the "failed to create ca_config_assets table" and "failed to add not_valid_after column to host_mdm_managed_certificates table" error messages), preserving the error chain for `errors.Is`/`errors.As`, consistent with sibling migrations.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 95 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand All @@ -31,7 +31,7 @@ func Up_20250304162702(tx *sql.Tx) error {
ADD COLUMN not_valid_after DATETIME(6) NULL
`)
if err != nil {
return fmt.Errorf("failed to add not_valid_after column to host_mdm_managed_certificates table: %s", err)
return fmt.Errorf("failed to add not_valid_after column to host_mdm_managed_certificates table: %w", err)
}
}
return nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func Up_20250331042354(tx *sql.Tx) error {
`)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 fmt.Errorf without %w breaks error chain in SCIM migration

Changed %s to %w in the fmt.Errorf call within Up_20250331042354, preserving the underlying error's type information for errors.Is/errors.As chains, consistent with other migrations in the package.

πŸ€– Prompt for AI agents
In server/datastore/mysql/migrations/tables/20250331042354_AddSCIMTables.go around line 68, review and complete this code-review fix: fmt.Errorf without %w breaks error chain in SCIM migration.
What the draft fix changed: Changed `%s` to `%w` in the `fmt.Errorf` call within `Up_20250331042354`, preserving the underlying error's type information for `errors.Is`/`errors.As` chains, consistent with other migrations in the package.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 95 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer


if err != nil {
return fmt.Errorf("failed to create scim tables: %s", err)
return fmt.Errorf("failed to create scim tables: %w", err)
}

return nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ func Up_20251124090450(tx *sql.Tx) error {
createdAt := time.Date(2025, 11, 19, 0, 0, 0, 0, time.UTC)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 Migration insert error message uses %s instead of %w, discarding error chain for FLEET_VAR_HOST_PLATFORM insert

In Up_20251124090450, both fmt.Errorf calls now use %w instead of %s to wrap the underlying err from sqlx.Named and tx.Exec, preserving the error chain for errors.Is/errors.Unwrap. Also normalized the capitalized "Failed" to lowercase "failed" to match Go error string conventions and the suggested fix.

πŸ€– Prompt for AI agents
In server/datastore/mysql/migrations/tables/20251124090450_AddHostPlatformFleetVar.go around line 24, review and complete this code-review fix: Migration insert error message uses %s instead of %w, discarding error chain for FLEET_VAR_HOST_PLATFORM insert.
What the draft fix changed: In Up_20251124090450, both `fmt.Errorf` calls now use `%w` instead of `%s` to wrap the underlying `err` from `sqlx.Named` and `tx.Exec`, preserving the error chain for `errors.Is`/`errors.Unwrap`. Also normalized the capitalized "Failed" to lowercase "failed" to match Go error string conventions and the suggested fix.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 95 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

stmt, args, err := sqlx.Named(insStmt, map[string]any{"created_at": createdAt})
if err != nil {
return fmt.Errorf("Failed to prepare insert for FLEET_VAR_HOST_PLATFORM: %s", err)
return fmt.Errorf("failed to prepare insert for FLEET_VAR_HOST_PLATFORM: %w", err)
}
_, err = tx.Exec(stmt, args...)
if err != nil {
return fmt.Errorf("failed to insert FLEET_VAR_HOST_PLATFORM into fleet_variables: %s", err)
return fmt.Errorf("failed to insert FLEET_VAR_HOST_PLATFORM into fleet_variables: %w", err)
}
return nil
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package tables

import (
"database/sql"
"fmt"
)

func init() {
Expand All @@ -12,7 +13,7 @@ func Up_20260217141240(tx *sql.Tx) error {
// Idempotent migration. Naturally re-runnable (UPDATE/MODIFY/JSON-config only).
_, err := tx.Exec(`UPDATE labels SET platform = '' WHERE platform NOT IN ('', 'centos', 'darwin', 'windows', 'ubuntu')`)
if err != nil {
return err
return fmt.Errorf("resetting invalid platform on labels: %w", err)
}
return nil
}
Comment on lines 13 to 19

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 Bare 'return err' in migration without contextual wrapping

In Up_20260217141240, wrapped the err returned from tx.Exec with fmt.Errorf("resetting invalid platform on labels: %w", err), and added the fmt import to support it. Down_20260217141240 has no error path (always returns nil), so no change was needed there.

πŸ€– Prompt for AI agents
In server/datastore/mysql/migrations/tables/20260217141240_ResetInvalidPlatformOnLabels.go around line 11, review and complete this code-review fix: Bare 'return err' in migration without contextual wrapping.
What the draft fix changed: In Up_20260217141240, wrapped the `err` returned from `tx.Exec` with `fmt.Errorf("resetting invalid platform on labels: %w", err)`, and added the `fmt` import to support it. Down_20260217141240 has no error path (always returns nil), so no change was needed there.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 90 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package tables

import (
"database/sql"
"fmt"
)

func init() {
Comment on lines 2 to 8

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 Migration 20260409153714 returns bare tx.Exec error without wrapping context

In Up_20260409153714, added the "fmt" import and wrapped the tx.Exec error with fmt.Errorf("create user_api_endpoints table: %w", err) instead of returning the bare err, matching the style of sibling migrations.

πŸ€– Prompt for AI agents
In server/datastore/mysql/migrations/tables/20260409153714_AddApiEndpointPermissionsTables.go around line 12, review and complete this code-review fix: Migration 20260409153714 returns bare tx.Exec error without wrapping context.
What the draft fix changed: In Up_20260409153714, added the "fmt" import and wrapped the tx.Exec error with fmt.Errorf("create user_api_endpoints table: %w", err) instead of returning the bare err, matching the style of sibling migrations.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 90 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand All @@ -22,7 +23,7 @@ func Up_20260409153714(tx *sql.Tx) error {
)
`)
if err != nil {
return err
return fmt.Errorf("create user_api_endpoints table: %w", err)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func Up_20260522195225(tx *sql.Tx) error {
ALTER TABLE host_managed_local_account_passwords
ADD KEY idx_hmlap_auto_rotate_at (auto_rotate_at)
`); err != nil {
return fmt.Errorf("adding rotation columns to host_managed_local_account_passwords: %w", err)
return fmt.Errorf("adding idx_hmlap_auto_rotate_at index to host_managed_local_account_passwords: %w", err)
}
}
return nil
Comment on lines 29 to 35

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 Duplicate error message on idempotent column-add migration

In Up_20260522195225, changed the error message in the second error branch (the ADD KEY / index-add failure) from "adding rotation columns to host_managed_local_account_passwords: %w" to "adding idx_hmlap_auto_rotate_at index to host_managed_local_account_passwords: %w", matching the suggested fix exactly and disambiguating it from the column-add error message above it.

πŸ€– Prompt for AI agents
In server/datastore/mysql/migrations/tables/20260522195225_AddManagedLocalAccountRotationColumns.go around line 22, review and complete this code-review fix: Duplicate error message on idempotent column-add migration.
What the draft fix changed: In Up_20260522195225, changed the error message in the second error branch (the ADD KEY / index-add failure) from "adding rotation columns to host_managed_local_account_passwords: %w" to "adding idx_hmlap_auto_rotate_at index to host_managed_local_account_passwords: %w", matching the suggested fix exactly and disambiguating it from the column-add error message above it.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 95 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand Down
2 changes: 1 addition & 1 deletion server/fleet/agent_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func SuggestAgentOptionsCorrection(err error) error {
if field := GetJSONUnknownField(err); field != nil {
correctKeyPath, keyErr := FindAgentOptionsKeyPath(*field)
if keyErr != nil {
return fmt.Errorf("error parsing generated agent options struct: %w", err)
return fmt.Errorf("error parsing generated agent options struct: %w", keyErr)
}
var keyPathJoined string
switch pathLen := len(correctKeyPath); {
Comment on lines 65 to 71

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 SuggestAgentOptionsCorrection swallows keyErr instead of wrapping it into the returned error chain

In SuggestAgentOptionsCorrection (server/fleet/agent_options.go), changed the error wrapping on the FindAgentOptionsKeyPath failure branch from fmt.Errorf("error parsing generated agent options struct: %w", err) to fmt.Errorf("error parsing generated agent options struct: %w", keyErr), so the actual cause (keyErr) is preserved in the returned error chain instead of the outer/original err.

πŸ€– Prompt for AI agents
In server/fleet/agent_options.go around line 63, review and complete this code-review fix: SuggestAgentOptionsCorrection swallows keyErr instead of wrapping it into the returned error chain.
What the draft fix changed: In SuggestAgentOptionsCorrection (server/fleet/agent_options.go), changed the error wrapping on the FindAgentOptionsKeyPath failure branch from `fmt.Errorf("error parsing generated agent options struct: %w", err)` to `fmt.Errorf("error parsing generated agent options struct: %w", keyErr)`, so the actual cause (keyErr) is preserved in the returned error chain instead of the outer/original err.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 97 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand Down
9 changes: 8 additions & 1 deletion server/logging/pubsub.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,13 @@ func (w *pubSubLogWriter) Write(ctx context.Context, logs []json.RawMessage) err
}

if len(data)+estimateAttributeSize(attributes) > pubsub.MaxPublishRequestBytes {
logPreview := log
if len(logPreview) > 100 {
logPreview = logPreview[:100]
}
w.logger.InfoContext(ctx, "dropping log over 10MB PubSub limit",
"size", len(data),
"log", string(log[:100])+"...",
"log", string(logPreview)+"...",
)
continue
}
Comment on lines 78 to 90

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 pubSubLogWriter.Write silently drops oversized messages without wrapping/propagating a warning error

In pubSubLogWriter.Write, added if result == nil { continue } in the second for _, result := range results loop, skipping oversized messages that were left as nil in the results slice, preventing the nil pointer dereference panic on result.Get(ctx).

πŸ€– Prompt for AI agents
In server/logging/pubsub.go around line 71, review and complete this code-review fix: pubSubLogWriter.Write silently drops oversized messages without wrapping/propagating a warning error.
What the draft fix changed: In `pubSubLogWriter.Write`, added `if result == nil { continue }` in the second `for _, result := range results` loop, skipping oversized messages that were left as nil in the `results` slice, preventing the nil pointer dereference panic on `result.Get(ctx)`.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 92 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Comment on lines 78 to 90

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 πŸ”΄ pubSubLogWriter oversized-log slicing can panic on short log payloads

In pubSubLogWriter.Write's oversized-message branch, replaced the unguarded string(log[:100]) with a length-checked logPreview variable (if len(logPreview) > 100 { logPreview = logPreview[:100] }) before slicing, preventing an index-out-of-range panic when log is shorter than 100 bytes.

πŸ€– Prompt for AI agents
In server/logging/pubsub.go around line 72, review and complete this code-review fix: pubSubLogWriter oversized-log slicing can panic on short log payloads.
What the draft fix changed: In `pubSubLogWriter.Write`'s oversized-message branch, replaced the unguarded `string(log[:100])` with a length-checked `logPreview` variable (`if len(logPreview) > 100 { logPreview = logPreview[:100] }`) before slicing, preventing an index-out-of-range panic when `log` is shorter than 100 bytes.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 90 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand All @@ -95,6 +99,9 @@ func (w *pubSubLogWriter) Write(ctx context.Context, logs []json.RawMessage) err

// Wait for each message to be pushed to the server
for _, result := range results {
if result == nil {
continue
}
_, err := result.Get(ctx)
if err != nil {
return ctxerr.Wrap(ctx, err, "pubsub publish")
Expand Down
2 changes: 1 addition & 1 deletion server/mail/ses.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func (s *sesSender) sendMail(ctx context.Context, e fleet.Email, msg []byte) err
SourceArn: &s.sourceArn,
})
if err != nil {
return err
return fmt.Errorf("send raw email via ses: %w", err)
}
return nil
}
Comment on lines 106 to 112

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 sesSender.sendMail returns bare err without wrapping context

In sesSender.sendMail (server/mail/ses.go), replaced return err with return fmt.Errorf("send raw email via ses: %w", err) to wrap the SendRawEmail error with call-boundary context, consistent with the wrapping pattern used elsewhere in the file (e.g. NewSESSender). No other logic changed.

πŸ€– Prompt for AI agents
In server/mail/ses.go around line 105, review and complete this code-review fix: sesSender.sendMail returns bare err without wrapping context.
What the draft fix changed: In `sesSender.sendMail` (server/mail/ses.go), replaced `return err` with `return fmt.Errorf("send raw email via ses: %w", err)` to wrap the SendRawEmail error with call-boundary context, consistent with the wrapping pattern used elsewhere in the file (e.g. NewSESSender). No other logic changed.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 95 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

4 changes: 2 additions & 2 deletions server/mdm/apple/cert.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,12 @@ func GetSignedAPNSCSR(client *http.Client, csr *x509.CertificateRequest) error {

req, err := http.NewRequest(http.MethodPost, u, bytes.NewReader(b))
if err != nil {
return err
return fmt.Errorf("creating csr signing request for fleetdm api: %w", err)
}

resp, err := client.Do(req)
if err != nil {
return err

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 GetSignedAPNSCSR returns raw errors from http.NewRequest/client.Do without wrapping

In GetSignedAPNSCSR (server/mdm/apple/cert.go), wrapped the bare return err from http.NewRequest with fmt.Errorf("creating csr signing request for fleetdm api: %w", err) and the bare return err from client.Do with fmt.Errorf("sending csr signing request to fleetdm api: %w", err), matching the exact wording used in the sibling function GetSignedAPNSCSRNoEmail.

πŸ€– Prompt for AI agents
In server/mdm/apple/cert.go around line 140, review and complete this code-review fix: GetSignedAPNSCSR returns raw errors from http.NewRequest/client.Do without wrapping.
What the draft fix changed: In GetSignedAPNSCSR (server/mdm/apple/cert.go), wrapped the bare `return err` from `http.NewRequest` with `fmt.Errorf("creating csr signing request for fleetdm api: %w", err)` and the bare `return err` from `client.Do` with `fmt.Errorf("sending csr signing request to fleetdm api: %w", err)`, matching the exact wording used in the sibling function GetSignedAPNSCSRNoEmail.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 95 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

return fmt.Errorf("sending csr signing request to fleetdm api: %w", err)
}
defer resp.Body.Close()

Expand Down
5 changes: 3 additions & 2 deletions server/mdm/apple/profile_verifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func VerifyHostMDMProfiles(ctx context.Context, ds fleet.ProfileVerificationStor

expectedByProfIdentifier, err := ds.GetHostMDMProfilesExpectedForVerification(ctx, host)
if err != nil {
return err
return ctxerr.Wrap(ctx, err, "getting expected MDM profiles for verification")
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 VerifyHostMDMProfiles returns underlying datastore errors unwrapped, losing call context

In VerifyHostMDMProfiles, the return err after ds.GetHostMDMProfilesExpectedForVerification(ctx, host) was changed to return ctxerr.Wrap(ctx, err, "getting expected MDM profiles for verification"), matching the ctxerr.Wrap convention used elsewhere in the file.

πŸ€– Prompt for AI agents
In server/mdm/apple/profile_verifier.go around line 60, review and complete this code-review fix: VerifyHostMDMProfiles returns underlying datastore errors unwrapped, losing call context.
What the draft fix changed: In VerifyHostMDMProfiles, the `return err` after `ds.GetHostMDMProfilesExpectedForVerification(ctx, host)` was changed to `return ctxerr.Wrap(ctx, err, "getting expected MDM profiles for verification")`, matching the ctxerr.Wrap convention used elsewhere in the file.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 90 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

missing := make([]string, 0, len(expectedByProfIdentifier))
Expand Down Expand Up @@ -85,7 +85,7 @@ func VerifyHostMDMProfiles(ctx context.Context, ds fleet.ProfileVerificationStor
if len(missing) > 0 {
counts, err := ds.GetHostMDMProfilesRetryCounts(ctx, host)
if err != nil {
return err
return ctxerr.Wrap(ctx, err, "getting host MDM profile retry counts")
}
retriesByProfileIdentifier := make(map[string]uint, len(counts))
for _, r := range counts {
Comment on lines 85 to 91

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 Retry-count lookup error returned bare, without ctxerr wrap, in VerifyHostMDMProfiles

In VerifyHostMDMProfiles, the return err after ds.GetHostMDMProfilesRetryCounts(ctx, host) was changed to return ctxerr.Wrap(ctx, err, "getting host MDM profile retry counts"), consistent with the ctxerr.Wrap pattern used throughout HandleHostMDMProfileInstallResult in the same file.

πŸ€– Prompt for AI agents
In server/mdm/apple/profile_verifier.go around line 84, review and complete this code-review fix: Retry-count lookup error returned bare, without ctxerr wrap, in VerifyHostMDMProfiles.
What the draft fix changed: In VerifyHostMDMProfiles, the `return err` after `ds.GetHostMDMProfilesRetryCounts(ctx, host)` was changed to `return ctxerr.Wrap(ctx, err, "getting host MDM profile retry counts")`, consistent with the ctxerr.Wrap pattern used throughout HandleHostMDMProfileInstallResult in the same file.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 90 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand Down Expand Up @@ -174,3 +174,4 @@ func HandleHostMDMProfileInstallResult(ctx context.Context, ds fleet.ProfileVeri
}
return nil
}

3 changes: 2 additions & 1 deletion server/mdm/internal/commonmdm/commonmdm.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package commonmdm

import (
"fmt"
"net/url"
"path"
)
Expand All @@ -10,7 +11,7 @@ import (
func ResolveURL(serverURL, relPath string, cleanQuery bool) (string, error) {
u, err := url.Parse(serverURL)
if err != nil {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 ResolveURL returns url.Parse error unwrapped, losing call-boundary context

In ResolveURL, wrapped the url.Parse(serverURL) error with fmt.Errorf("parsing server URL: %w", err) instead of returning it bare, and added the fmt import to support it.

πŸ€– Prompt for AI agents
In server/mdm/internal/commonmdm/commonmdm.go around line 12, review and complete this code-review fix: ResolveURL returns url.Parse error unwrapped, losing call-boundary context.
What the draft fix changed: In ResolveURL, wrapped the `url.Parse(serverURL)` error with `fmt.Errorf("parsing server URL: %w", err)` instead of returning it bare, and added the `fmt` import to support it.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 95 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

return "", err
return "", fmt.Errorf("parsing server URL: %w", err)
}
u.Path = path.Join(u.Path, relPath)
if cleanQuery {
Expand Down
3 changes: 2 additions & 1 deletion server/mdm/nanodep/client/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {

session, err = DoAuth(t.client, sessionReq, tokens)
if err != nil {
return nil, err
return nil, fmt.Errorf("transport: performing dep auth: %w", err)
}

// save our session token for use by following requests
Comment on lines 234 to 240

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 Bare error return without wrapping in SetSessionToken call site

In RoundTrip, changed return nil, err after session, err = DoAuth(t.client, sessionReq, tokens) to return nil, fmt.Errorf("transport: performing dep auth: %w", err), wrapping the error with call-boundary context consistent with the rest of the function.

πŸ€– Prompt for AI agents
In server/mdm/nanodep/client/transport.go around line 227, review and complete this code-review fix: Bare error return without wrapping in SetSessionToken call site.
What the draft fix changed: In `RoundTrip`, changed `return nil, err` after `session, err = DoAuth(t.client, sessionReq, tokens)` to `return nil, fmt.Errorf("transport: performing dep auth: %w", err)`, wrapping the error with call-boundary context consistent with the rest of the function.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 90 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand Down Expand Up @@ -277,3 +277,4 @@ func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {

return resp, nil
}

5 changes: 2 additions & 3 deletions server/mdm/scep/cmd/scepclient/scepclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,7 @@ func run(cfg runCfg) error {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 os.Exit called immediately after printing error instead of returning wrapped error from loadOrMakeCSR failure

In run(), replaced the fmt.Println(err); os.Exit(1) block following loadOrMakeCSR with return fmt.Errorf("load or make CSR: %w", err), matching the suggested fix and the error-propagation contract used elsewhere in the function.

πŸ€– Prompt for AI agents
In server/mdm/scep/cmd/scepclient/scepclient.go around line 88, review and complete this code-review fix: os.Exit called immediately after printing error instead of returning wrapped error from loadOrMakeCSR failure.
What the draft fix changed: In run(), replaced the `fmt.Println(err); os.Exit(1)` block following `loadOrMakeCSR` with `return fmt.Errorf("load or make CSR: %w", err)`, matching the suggested fix and the error-propagation contract used elsewhere in the function.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 95 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

csr, err := loadOrMakeCSR(cfg.csrPath, opts)
if err != nil {
fmt.Println(err)
os.Exit(1)
return fmt.Errorf("load or make CSR: %w", err)
}

var self *x509.Certificate
Expand Down Expand Up @@ -256,7 +255,7 @@ func validateFlags(keyPath, serverURL, caFingerprint string, useKeyEnciphermentS
}
_, err := url.Parse(serverURL)
if err != nil {
return fmt.Errorf("invalid server-url flag parameter %s", err)
return fmt.Errorf("invalid server-url flag parameter: %w", err)
}
if caFingerprint != "" && useKeyEnciphermentSelector {
return errors.New("ca-fingerprint and key-encipherment-selector can't be used at the same time")
Comment on lines 255 to 261

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 Bare fmt.Errorf without %w wrapping loses causal chain in scepclient.go

In validateFlags(), changed fmt.Errorf("invalid server-url flag parameter %s", err) to fmt.Errorf("invalid server-url flag parameter: %w", err) so the underlying url.Parse error is wrapped with %w, preserving the error chain for errors.Is/As. Other fmt.Errorf calls in the file (e.g. FAILURE status, invalid hash length) do not wrap an underlying error and were left unchanged per the finding's own scope.

πŸ€– Prompt for AI agents
In server/mdm/scep/cmd/scepclient/scepclient.go around line 214, review and complete this code-review fix: Bare fmt.Errorf without %w wrapping loses causal chain in scepclient.go.
What the draft fix changed: In validateFlags(), changed `fmt.Errorf("invalid server-url flag parameter %s", err)` to `fmt.Errorf("invalid server-url flag parameter: %w", err)` so the underlying url.Parse error is wrapped with %w, preserving the error chain for errors.Is/As. Other fmt.Errorf calls in the file (e.g. FAILURE status, invalid hash length) do not wrap an underlying error and were left unchanged per the finding's own scope.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 90 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand Down
4 changes: 2 additions & 2 deletions server/platform/http/post_json.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ func (e *errWithStatus) StatusCode() int {
func PostJSONWithTimeout(ctx context.Context, url string, v any, logger *slog.Logger) error {
jsonBytes, err := json.Marshal(v)
if err != nil {
return err
return fmt.Errorf("marshal json body: %w", err)
}

client := fleethttp.NewClient(fleethttp.WithTimeout(30 * time.Second))
req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewBuffer(jsonBytes))
if err != nil {
return err
return fmt.Errorf("build POST request: %w", err)
}

req.Header.Set("Content-Type", "application/json")
Comment on lines 33 to 45

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 json.Marshal error returned bare in PostJSONWithTimeout

In PostJSONWithTimeout, wrapped the bare return err for the json.Marshal failure with fmt.Errorf("marshal json body: %w", err) and the bare return err for http.NewRequestWithContext failure with fmt.Errorf("build POST request: %w", err), matching the wrapping convention already used for the client.Do error later in the same function.

πŸ€– Prompt for AI agents
In server/platform/http/post_json.go around line 32, review and complete this code-review fix: json.Marshal error returned bare in PostJSONWithTimeout.
What the draft fix changed: In PostJSONWithTimeout, wrapped the bare `return err` for the json.Marshal failure with `fmt.Errorf("marshal json body: %w", err)` and the bare `return err` for http.NewRequestWithContext failure with `fmt.Errorf("build POST request: %w", err)`, matching the wrapping convention already used for the client.Do error later in the same function.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 95 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand Down
5 changes: 1 addition & 4 deletions server/service/client_setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@ func (c *Client) Setup(email, name, password, org string) (string, error) {
)
}

if response.StatusCode != http.StatusOK {
return "", fmt.Errorf("setup got HTTP %d, expected 200", response.StatusCode)
}

var responseBody setupResponse
err = json.NewDecoder(response.Body).Decode(&responseBody)
if err != nil {
Comment on lines 42 to 47

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 Redundant status-code check duplicated immediately after the first check in Setup

Removed the redundant, unreachable second if response.StatusCode != http.StatusOK block in Setup (server/service/client_setup.go), which was dead code following the first identical check that already returns on error.

πŸ€– Prompt for AI agents
In server/service/client_setup.go around line 38, review and complete this code-review fix: Redundant status-code check duplicated immediately after the first check in Setup.
What the draft fix changed: Removed the redundant, unreachable second `if response.StatusCode != http.StatusOK` block in `Setup` (server/service/client_setup.go), which was dead code following the first identical check that already returns on error.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 95 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

Expand All @@ -58,3 +54,4 @@ func (c *Client) Setup(email, name, password, org string) (string, error) {

return *responseBody.Token, nil
}

4 changes: 2 additions & 2 deletions server/service/openframe/openframe_token_refresher.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func (tr *OpenframeTokenRefresher) Start() error {
log.Info().Msg("Scheduling token refresh job")

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 Cron start error returned without call-boundary context beyond the static string

In Start(), changed the error wrapping from fmt.Errorf("failed to schedule token refresh job: %v", err) to fmt.Errorf("failed to schedule token refresh job: %w", err), preserving the wrapped-error chain from cron.AddFunc so downstream errors.Is/As calls work correctly.

πŸ€– Prompt for AI agents
In server/service/openframe/openframe_token_refresher.go around line 31, review and complete this code-review fix: Cron start error returned without call-boundary context beyond the static string.
What the draft fix changed: In Start(), changed the error wrapping from `fmt.Errorf("failed to schedule token refresh job: %v", err)` to `fmt.Errorf("failed to schedule token refresh job: %w", err)`, preserving the wrapped-error chain from cron.AddFunc so downstream errors.Is/As calls work correctly.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟒 95 high β€” react πŸ‘/πŸ‘Ž to teach the reviewer

_, err := tr.cron.AddFunc("*/5 * * * * *", tr.refreshToken)
if err != nil {
return fmt.Errorf("failed to schedule token refresh job: %v", err)
return fmt.Errorf("failed to schedule token refresh job: %w", err)
}
tr.cron.Start()
log.Info().Msg("Token refresh job started")
Expand Down Expand Up @@ -73,4 +73,4 @@ func (tr *OpenframeTokenRefresher) refreshToken() {

tr.authorizationManager.UpdateToken(token)
log.Info().Msg("Openframe token refreshed")
}
}
Loading