{"record":{"id":"3b27b52050e45880","repo":"gofr-dev/gofr","slug":"maxidleconnsperhost-cannot-be-negative","errorCode":null,"errorMessage":"MaxIdleConnsPerHost cannot be negative","messagePattern":"MaxIdleConnsPerHost cannot be negative","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/gofr/service/connection_pool.go","lineNumber":12,"sourceCode":"package service\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"time\"\n)\n\nvar (\n\terrNegativeMaxIdleConns        = errors.New(\"MaxIdleConns cannot be negative\")\n\terrNegativeMaxIdleConnsPerHost = errors.New(\"MaxIdleConnsPerHost cannot be negative\")\n\terrNegativeIdleConnTimeout     = errors.New(\"IdleConnTimeout cannot be negative\")\n)\n\n// ConnectionPoolConfig holds the configuration for HTTP connection pool settings.\n// It customizes the HTTP transport layer to optimize connection reuse for high-frequency requests.\n//\n// Note: This configuration must be applied first when using multiple options with AddHTTPService,\n// as it needs to access the underlying HTTP client transport. If applied after wrapper options\n// (CircuitBreaker, Retry, OAuth), it will be silently ignored.\n//\n// Example:\n//\n//\tapp.AddHTTPService(\"api-service\", \"https://api.example.com\",\n//\t    &service.ConnectionPoolConfig{\n//\t        MaxIdleConns:        100,\n//\t        MaxIdleConnsPerHost: 20,\n//\t        IdleConnTimeout:     90 * time.Second,\n//\t    },","sourceCodeStart":1,"sourceCodeEnd":30,"githubUrl":"https://github.com/gofr-dev/gofr/blob/187eb24962502e91f1fee856230670958b66e89c/pkg/gofr/service/connection_pool.go#L1-L30","documentation":"errNegativeMaxIdleConnsPerHost is a validation sentinel: ConnectionPoolConfig.Validate rejects a negative MaxIdleConnsPerHost because http.Transport requires a non-negative per-host idle connection limit. Validate wraps it with the offending value before returning.","triggerScenarios":"ConnectionPoolConfig{MaxIdleConnsPerHost: -1} passed to Validate(), or added to a service via AddOption/AddHTTPService which runs Validate first.","commonSituations":"Formula-derived per-host values (e.g. dividing totals) going negative on empty inputs; YAML/JSON config with negative numbers; misunderstanding that 0 is allowed (it means default/1) while negatives are not.","solutions":["Set MaxIdleConnsPerHost to a non-negative value in the config source","Clamp negative computed values to 0 before constructing ConnectionPoolConfig","Fail fast at startup by calling Validate() immediately after loading config","Match with errors.Is(err, errNegativeMaxIdleConnsPerHost) in config error handling to pinpoint the field"],"exampleFix":"// before\npool := &ConnectionPoolConfig{MaxIdleConnsPerHost: total / hosts} // can be negative\n// after\nperHost := total / max(hosts, 1)\nif perHost < 0 { perHost = 0 }\npool := &ConnectionPoolConfig{MaxIdleConnsPerHost: perHost}","handlingStrategy":"validation","validationCode":"if pool.MaxIdleConnsPerHost < 0 {\n    return fmt.Errorf(\"MaxIdleConnsPerHost must be >= 0, got %d\", pool.MaxIdleConnsPerHost)\n}\nif err := pool.Validate(); err != nil { return err }","typeGuard":"func validPerHost(v int) bool { return v >= 0 }","tryCatchPattern":"if err := pool.Validate(); err != nil {\n    if errors.Is(err, errNegativeMaxIdleConnsPerHost) {\n        pool.MaxIdleConnsPerHost = 2 // sane default\n    } else {\n        return err\n    }\n}","preventionTips":["Guard division/derivation of per-host values against zero/negative inputs","Clamp to 0 before constructing the config","Validate at startup so bad config fails fast","Use errors.Is(err, errNegativeMaxIdleConnsPerHost) for field-level messages"],"tags":["http-client","configuration","connection-pool","validation"],"backgroundTag":"invalid-config-value","analyzedSha":"187eb24962502e91f1fee856230670958b66e89c","analyzedAt":"2026-09-01T20:34:54.554Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}