Skip to content

[duplicate-code] Duplicate Code Pattern: Backend Tool Call Execution Block #1662

@github-actions

Description

@github-actions

Part of duplicate code analysis: #1661

Summary

Three functions in internal/server/unified.go contain a near-identical block for executing a backend MCP tool call over a session-aware connection. The shared logic — launching/getting a connection, sending a tools/call request, checking the error response, and unmarshalling the JSON result — is ~18 lines long and diverges only in return types and the logging context.

Duplication Details

Pattern: launch connection → SendRequestWithServerID → check error → unmarshal result

  • Severity: High
  • Occurrences: 3
  • Locations:
    • internal/server/unified.go lines 569–604 (guardBackendCaller.CallTool)
    • internal/server/unified.go lines 703–730 (callBackendTool, Phase 3)
    • internal/server/unified.go lines 269–295 (registerToolsFromBackend, partial – uses tools/list)

Code in guardBackendCaller.CallTool (lines 569–604):

conn, err := launcher.GetOrLaunchForSession(g.server.launcher, g.serverID, sessionID.(string))
if err != nil {
    return nil, fmt.Errorf("failed to connect: %w", err)
}
response, err := conn.SendRequestWithServerID(g.ctx, "tools/call", map[string]interface{}{
    "name":      toolName,
    "arguments": args,
}, g.serverID)
if err != nil {
    return nil, err
}
if response.Error != nil {
    return nil, fmt.Errorf("backend error: code=%d, message=%s", response.Error.Code, response.Error.Message)
}
var result interface{}
if err := json.Unmarshal(response.Result, &result); err != nil {
    return nil, fmt.Errorf("failed to parse result: %w", err)
}
return result, nil

Nearly identical block in callBackendTool Phase 3 (lines 703–730):

conn, err := launcher.GetOrLaunchForSession(us.launcher, serverID, sessionID)
if err != nil {
    return newErrorCallToolResult(fmt.Errorf("failed to connect: %w", err))
}
response, err := conn.SendRequestWithServerID(ctx, "tools/call", map[string]interface{}{
    "name":      toolName,
    "arguments": args,
}, serverID)
if err != nil {
    return newErrorCallToolResult(err)
}
if response.Error != nil {
    return newErrorCallToolResult(fmt.Errorf("backend error: code=%d, message=%s", response.Error.Code, response.Error.Message))
}
var backendResult interface{}
if err := json.Unmarshal(response.Result, &backendResult); err != nil {
    return newErrorCallToolResult(fmt.Errorf("failed to parse result: %w", err))
}

The only structural differences are:

  1. Return type: (interface{}, error) vs (*sdk.CallToolResult, interface{}, error)
  2. Error wrapper: return nil, err vs return newErrorCallToolResult(err)
  3. Session resolution: g.ctx.Value(...) vs us.getSessionID(ctx) (already resolved before the block)

Impact Analysis

  • Maintainability: Any change to error message format, response error handling, or JSON unmarshal logic must be applied in both places. The current identical error string "backend error: code=%d, message=%s" is already evidence of copy-paste.
  • Bug Risk: Medium — a future fix to one branch (e.g., adding retry logic or telemetry) is likely to miss the other.
  • Code Bloat: ~18 lines duplicated per instance.

Refactoring Recommendations

  1. Extract executeBackendToolCall helper

    • Location: internal/server/unified.go (or new internal/server/backend_call.go)
    • Signature: func executeBackendToolCall(ctx context.Context, l *launcher.Launcher, serverID, toolName string, args interface{}) (interface{}, error)
    • Returns raw (interface{}, error) — the callers adapt the result to their specific return types.
    • guardBackendCaller.CallTool can call this directly.
    • callBackendTool calls this, then applies DIFC Phase 4–5 on top.
    • Estimated effort: ~1 hour, low risk.
  2. Align session ID resolution before the shared block

    • guardBackendCaller.CallTool extracts the session ID inline via g.ctx.Value(...).
    • Extracting this to before the helper call aligns with how callBackendTool already calls us.getSessionID(ctx) first.

Implementation Checklist

  • Review duplication findings
  • Extract executeBackendToolCall(ctx, launcher, serverID, toolName, args) helper
  • Update guardBackendCaller.CallTool to use helper
  • Update callBackendTool Phase 3 to use helper
  • Verify registerToolsFromBackend pattern (uses tools/list — only first half overlaps; can share connect+error pattern)
  • Update tests
  • Verify no functionality broken

Parent Issue

See parent analysis report: #1661
Related to #1661

Generated by Duplicate Code Detector

  • expires on Mar 15, 2026, 3:01 AM UTC

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions