From b311fc8db0ac13b294b3f05972381013cf1033ed Mon Sep 17 00:00:00 2001 From: Joe Riddle Date: Tue, 24 Mar 2026 16:01:23 -0600 Subject: [PATCH 1/5] fix nil pointer dereference in handleStopWorkload When RequestMany returned an error, the return statement was inside the inner error check instead of the outer one, causing execution to fall through and call the nil msgs callback. Co-Authored-By: Claude Opus 4.6 (1M context) Signed-off-by: Joe Riddle --- handlers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/handlers.go b/handlers.go index 73b09016..fd8d39e8 100644 --- a/handlers.go +++ b/handlers.go @@ -372,8 +372,8 @@ func (n *NexNode) handleStopWorkload() func(micro.Request) { err = r.RespondJSON(ret) if err != nil { n.logger.Error("failed to respond to stop workload request", slog.String("err", err.Error())) - return } + return } msgs(func(m *nats.Msg, e error) bool { From 3caa56115bbac18bf2bb87faeef1a653cda7bb6e Mon Sep 17 00:00:00 2001 From: Joe Riddle Date: Tue, 24 Mar 2026 16:11:00 -0600 Subject: [PATCH 2/5] fix data race in StartLocalBinaryAgent Use cmd.Wait() instead of cmd.Process.Wait() to ensure I/O pipe-copying goroutines complete before returning, preventing a race between the exec package's internal goroutine writing to the logger buffer and test code reading it. Co-Authored-By: Claude Opus 4.6 (1M context) Signed-off-by: Joe Riddle --- internal/watcher.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/watcher.go b/internal/watcher.go index ae02fe3e..50e15010 100644 --- a/internal/watcher.go +++ b/internal/watcher.go @@ -228,11 +228,11 @@ func (a *AgentWatcher) StartLocalBinaryAgent(ap *AgentProcess, regCreds *models. ap.agentLock.Unlock() - state, err := cmd.Process.Wait() + err = cmd.Wait() if err != nil { a.logger.Error("Nexlet process exited with error", slog.Int("process", ap.Process.Pid), slog.String("err", err.Error())) - } else if state != nil && ap.state != models.AgentStateStopping || ap.state != models.AgentStateLameduck { - a.logger.Warn("Nexlet process unexpectedly exited with state", slog.Any("state", state), slog.Int("process", ap.Process.Pid)) + } else if cmd.ProcessState != nil && ap.state != models.AgentStateStopping || ap.state != models.AgentStateLameduck { + a.logger.Warn("Nexlet process unexpectedly exited with state", slog.Any("state", cmd.ProcessState), slog.Int("process", ap.Process.Pid)) } a.agentCount-- From da8b869b33aa003a5c98746f0998906ac10134e4 Mon Sep 17 00:00:00 2001 From: Joe Riddle Date: Tue, 24 Mar 2026 16:51:59 -0600 Subject: [PATCH 3/5] fix operator precedence bug in unexpected exit warning Co-Authored-By: Claude Opus 4.6 (1M context) Signed-off-by: Joe Riddle --- internal/watcher.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/watcher.go b/internal/watcher.go index 50e15010..644b2379 100644 --- a/internal/watcher.go +++ b/internal/watcher.go @@ -231,7 +231,7 @@ func (a *AgentWatcher) StartLocalBinaryAgent(ap *AgentProcess, regCreds *models. err = cmd.Wait() if err != nil { a.logger.Error("Nexlet process exited with error", slog.Int("process", ap.Process.Pid), slog.String("err", err.Error())) - } else if cmd.ProcessState != nil && ap.state != models.AgentStateStopping || ap.state != models.AgentStateLameduck { + } else if cmd.ProcessState != nil && ap.state != models.AgentStateStopping && ap.state != models.AgentStateLameduck { a.logger.Warn("Nexlet process unexpectedly exited with state", slog.Any("state", cmd.ProcessState), slog.Int("process", ap.Process.Pid)) } From 3c5602cfdde3b88e4ed520b7bf2037c4d4f13a5d Mon Sep 17 00:00:00 2001 From: Joe Riddle Date: Tue, 24 Mar 2026 17:02:06 -0600 Subject: [PATCH 4/5] test: increase auction stall because CI runners are slow Signed-off-by: Joe Riddle --- client/client_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/client_test.go b/client/client_test.go index fa49f3d2..8883bb32 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -355,7 +355,7 @@ func TestNexClient_CloneWorkload(t *testing.T) { be.NilErr(t, err) defer nc.Close() - client, err := NewClient(context.Background(), nc, "user", WithAuctionStall(1*time.Second)) + client, err := NewClient(context.Background(), nc, "user", WithAuctionStall(5*time.Second)) be.NilErr(t, err) be.Nonzero(t, client) From a67d4b992c2c6e4b0feb99c279f14dce9658cde5 Mon Sep 17 00:00:00 2001 From: Joe Riddle Date: Wed, 25 Mar 2026 08:55:07 -0600 Subject: [PATCH 5/5] fix: check nil-check micro on Shutdown Signed-off-by: Joe Riddle --- sdk/go/agent/runner.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sdk/go/agent/runner.go b/sdk/go/agent/runner.go index 6782bad0..e65cbc7d 100644 --- a/sdk/go/agent/runner.go +++ b/sdk/go/agent/runner.go @@ -314,6 +314,9 @@ func (a *Runner) performHeartbeat() { } func (a *Runner) Shutdown() error { + if a.micro == nil { + return nil + } return a.micro.Stop() }