Skip to content

[duplicate-code] 🔍 Duplicate Code Pattern: Default Gateway Configuration Initialization #1009

@github-actions

Description

@github-actions

Part of duplicate code analysis: #1006

Summary

Medium-severity duplication where default gateway configuration values (Port, StartupTimeout, ToolTimeout) are assigned in multiple locations across config_core.go and config_stdin.go. This creates maintenance burden when default values need to change.

Duplication Details

Pattern: Repeated Default Value Assignments

  • Severity: MEDIUM
  • Occurrences: 2+ locations (9+ lines each)
  • Locations:
    • internal/config/config_core.go lines 196-204 (applyDefaults function)
    • internal/config/config_stdin.go lines 138-143 (convertStdinConfig - initial struct creation)
    • internal/config/config_stdin.go lines 159-161 (convertStdinConfig - nil gateway case)

Code Sample - config_core.go (lines 196-204):

func applyDefaults(cfg *Config) {
    // Apply gateway defaults
    if cfg.Gateway.Port == 0 {
        cfg.Gateway.Port = DefaultPort
    }
    if cfg.Gateway.StartupTimeout == 0 {
        cfg.Gateway.StartupTimeout = DefaultStartupTimeout
    }
    if cfg.Gateway.ToolTimeout == 0 {
        cfg.Gateway.ToolTimeout = DefaultToolTimeout
    }
    // ... more defaults
}

Code Sample - config_stdin.go (lines 138-143):

cfg.Gateway = &GatewayConfig{
    Port:           DefaultPort,
    StartupTimeout: DefaultStartupTimeout,
    ToolTimeout:    DefaultToolTimeout,
}

Code Sample - config_stdin.go (lines 159-161):

if cfg.Gateway == nil {
    cfg.Gateway = &GatewayConfig{
        Port:           DefaultPort,
        StartupTimeout: DefaultStartupTimeout,
        ToolTimeout:    DefaultToolTimeout,
    }
}

Impact Analysis

  • Maintainability: MEDIUM - Changing a default value requires updates in 3 locations
  • Bug Risk: MEDIUM - Easy to miss one location when updating defaults, causing inconsistent behavior
  • Code Consistency: Different initialization strategies (zero-check vs struct literal) for same defaults
  • Configuration Reliability: Inconsistent defaults could cause subtle bugs in different config loading paths

Refactoring Recommendations

1. Create Unified Default Config Constructor

Recommended implementation:

// Add to internal/config/config_core.go near DefaultPort constants

// NewDefaultGatewayConfig creates a GatewayConfig with all default values applied.
// This ensures consistent defaults across TOML config loading and JSON stdin parsing.
func NewDefaultGatewayConfig() *GatewayConfig {
    return &GatewayConfig{
        Port:           DefaultPort,
        StartupTimeout: DefaultStartupTimeout,
        ToolTimeout:    DefaultToolTimeout,
        // Add other gateway defaults as they're added
    }
}

Refactored config_core.go applyDefaults (lines 196-204):

func applyDefaults(cfg *Config) {
    // If gateway is nil or has zero values, apply defaults
    if cfg.Gateway == nil {
        cfg.Gateway = NewDefaultGatewayConfig()
        return
    }
    
    // Apply defaults for individual zero-valued fields
    defaults := NewDefaultGatewayConfig()
    if cfg.Gateway.Port == 0 {
        cfg.Gateway.Port = defaults.Port
    }
    if cfg.Gateway.StartupTimeout == 0 {
        cfg.Gateway.StartupTimeout = defaults.StartupTimeout
    }
    if cfg.Gateway.ToolTimeout == 0 {
        cfg.Gateway.ToolTimeout = defaults.ToolTimeout
    }
}

Refactored config_stdin.go (lines 138-143, 159-161):

// Line 138-143: Replace struct literal
cfg.Gateway = NewDefaultGatewayConfig()

// Line 159-161: Replace struct literal
if cfg.Gateway == nil {
    cfg.Gateway = NewDefaultGatewayConfig()
}
  • Estimated effort: 2-3 hours (create function, refactor 3 locations, verify tests)
  • Benefits:
    • Single source of truth for all gateway defaults
    • Easy to add new default fields in future
    • Consistent initialization across config loading paths
    • Self-documenting code
    • Future-proof against new optional fields

2. Alternative: Use Const Struct Pattern

// Define default values as a reusable struct
var DefaultGatewayConfig = GatewayConfig{
    Port:           DefaultPort,
    StartupTimeout: DefaultStartupTimeout,
    ToolTimeout:    DefaultToolTimeout,
}

// Usage: Copy defaults
cfg.Gateway = &DefaultGatewayConfig
// or
*cfg.Gateway = DefaultGatewayConfig

Note: This approach requires careful handling to avoid shared pointer issues.

Implementation Checklist

  • Review approach with team (constructor function vs const struct)
  • Implement NewDefaultGatewayConfig() function
  • Refactor config_core.go applyDefaults() to use constructor
  • Refactor config_stdin.go convertStdinConfig() to use constructor (2 locations)
  • Verify all configuration tests pass
  • Test TOML config loading with missing gateway fields
  • Test JSON stdin config with missing/nil gateway
  • Test config with partial gateway fields (mix of defaults and custom)
  • Update documentation if needed

Parent Issue

See parent analysis report: #1006
Related to #1006

Generated by Duplicate Code Detector

  • expires on Feb 24, 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