Skip to content

Commit 6d31272

Browse files
committed
fix: nil pointer dereference in ReportTask
Change-Id: I9a9886e004fb377950be523a79a1a51a3c954d5b Signed-off-by: Thomas Kosiewski <tk@coder.com>
1 parent 6bf2ec3 commit 6d31272

File tree

3 files changed

+64
-2
lines changed

3 files changed

+64
-2
lines changed

coderd/mcp/mcp.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,15 @@ func (s *Server) RegisterTools(client *codersdk.Client) error {
7979
return xerrors.Errorf("failed to initialize tool dependencies: %w", err)
8080
}
8181

82-
// Register all available tools
82+
// Register all available tools, but exclude tools that require dependencies not available in the
83+
// remote MCP context
8384
for _, tool := range toolsdk.All {
85+
if tool.Name == toolsdk.ToolNameReportTask {
86+
continue
87+
}
88+
8489
s.mcpServer.AddTools(mcpFromSDK(tool, toolDeps))
8590
}
86-
8791
return nil
8892
}
8993

codersdk/toolsdk/toolsdk.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,10 @@ ONLY report an "idle" or "failure" state if you have FULLY completed the task.
253253
if len(args.Summary) > 160 {
254254
return codersdk.Response{}, xerrors.New("summary must be less than 160 characters")
255255
}
256+
// Check if task reporting is available to prevent nil pointer dereference
257+
if deps.report == nil {
258+
return codersdk.Response{}, xerrors.New("task reporting not available. Please ensure a task reporter is configured.")
259+
}
256260
err := deps.report(args)
257261
if err != nil {
258262
return codersdk.Response{}, err

codersdk/toolsdk/toolsdk_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,3 +686,57 @@ func TestMain(m *testing.M) {
686686

687687
os.Exit(code)
688688
}
689+
690+
func TestReportTaskNilPointerDeref(t *testing.T) {
691+
t.Parallel()
692+
693+
// Create deps without a task reporter (simulating remote MCP server scenario)
694+
client, _ := coderdtest.NewWithDatabase(t, nil)
695+
deps, err := toolsdk.NewDeps(client)
696+
require.NoError(t, err)
697+
698+
// Prepare test arguments
699+
args := toolsdk.ReportTaskArgs{
700+
Summary: "Test task",
701+
Link: "https://example.com",
702+
State: string(codersdk.WorkspaceAppStatusStateWorking),
703+
}
704+
705+
_, err = toolsdk.ReportTask.Handler(t.Context(), deps, args)
706+
707+
// We expect an error, not a panic
708+
require.Error(t, err)
709+
require.Contains(t, err.Error(), "task reporting not available")
710+
}
711+
712+
func TestReportTaskWithReporter(t *testing.T) {
713+
t.Parallel()
714+
715+
// Create deps with a task reporter
716+
client, _ := coderdtest.NewWithDatabase(t, nil)
717+
718+
called := false
719+
reporter := func(args toolsdk.ReportTaskArgs) error {
720+
called = true
721+
require.Equal(t, "Test task", args.Summary)
722+
require.Equal(t, "https://example.com", args.Link)
723+
require.Equal(t, string(codersdk.WorkspaceAppStatusStateWorking), args.State)
724+
return nil
725+
}
726+
727+
deps, err := toolsdk.NewDeps(client, toolsdk.WithTaskReporter(reporter))
728+
require.NoError(t, err)
729+
730+
args := toolsdk.ReportTaskArgs{
731+
Summary: "Test task",
732+
Link: "https://example.com",
733+
State: string(codersdk.WorkspaceAppStatusStateWorking),
734+
}
735+
736+
result, err := toolsdk.ReportTask.Handler(t.Context(), deps, args)
737+
require.NoError(t, err)
738+
require.True(t, called)
739+
740+
// Verify response
741+
require.Equal(t, "Thanks for reporting!", result.Message)
742+
}

0 commit comments

Comments
 (0)