Skip to content

Commit 10fb76f

Browse files
committed
fix: nil pointer dereference in ReportTask
1 parent 38755e2 commit 10fb76f

File tree

3 files changed

+73
-2
lines changed

3 files changed

+73
-2
lines changed

coderd/mcp/mcp.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,17 @@ 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+
// Skip ReportTask tool in MCP context since we don't have a task reporter configured
86+
// This prevents the nil pointer dereference panic
87+
if tool.Name == toolsdk.ToolNameReportTask {
88+
continue
89+
}
90+
8491
s.mcpServer.AddTools(mcpFromSDK(tool, toolDeps))
8592
}
86-
8793
return nil
8894
}
8995

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: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,3 +686,64 @@ 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 MCP server scenario)
694+
client, _ := coderdtest.NewWithDatabase(t, nil) // Use a proper test client
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+
// This should panic with nil pointer dereference if the bug is present
706+
ctx := t.Context()
707+
708+
// Attempt to call the handler - this should cause the panic described in the issue
709+
_, err = toolsdk.ReportTask.Handler(ctx, deps, args)
710+
711+
// We expect an error, not a panic
712+
require.Error(t, err)
713+
require.Contains(t, err.Error(), "task reporting not available")
714+
}
715+
716+
func TestReportTaskWithReporter(t *testing.T) {
717+
t.Parallel()
718+
719+
// Create deps with a task reporter
720+
client, _ := coderdtest.NewWithDatabase(t, nil) // Use a proper test client
721+
722+
called := false
723+
reporter := func(args toolsdk.ReportTaskArgs) error {
724+
called = true
725+
require.Equal(t, "Test task", args.Summary)
726+
require.Equal(t, "https://example.com", args.Link)
727+
require.Equal(t, string(codersdk.WorkspaceAppStatusStateWorking), args.State)
728+
return nil
729+
}
730+
731+
deps, err := toolsdk.NewDeps(client, toolsdk.WithTaskReporter(reporter))
732+
require.NoError(t, err)
733+
734+
// Prepare test arguments
735+
args := toolsdk.ReportTaskArgs{
736+
Summary: "Test task",
737+
Link: "https://example.com",
738+
State: string(codersdk.WorkspaceAppStatusStateWorking),
739+
}
740+
741+
// This should work correctly
742+
ctx := t.Context()
743+
result, err := toolsdk.ReportTask.Handler(ctx, deps, args)
744+
require.NoError(t, err)
745+
require.True(t, called)
746+
747+
// Verify response
748+
require.Equal(t, "Thanks for reporting!", result.Message)
749+
}

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