Skip to content

Commit d159578

Browse files
authored
fix: fix nil pointer dereference in ReportTask (#19045)
This pull request addresses a bug related to a nil pointer dereference in the task reporting functionality. ### Bug Fixes and Error Handling: * Updated `RegisterTools` in `mcp.go` to skip registering the `ReportTask` tool in the remote MCP context when a task reporter is not configured, preventing potential nil pointer dereference panics. * Added a check in `toolsdk.go` to ensure task reporting dependencies are available before invoking the reporter, returning an appropriate error if not. ### Test Coverage: * Added `TestReportTaskNilPointerDeref` in `toolsdk_test.go` to verify that the system does not panic when task reporting dependencies are missing and instead returns a clear error message. * Added `TestReportTaskWithReporter` in `toolsdk_test.go` to validate correct behavior when a task reporter is configured, ensuring the handler processes the request as expected. Signed-off-by: Thomas Kosiewski <tk@coder.com>
1 parent 6bf2ec3 commit d159578

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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy