{"id":"a34c5e705026d9d3","repo":"labstack/echo","slug":"timeout-must-be-set","errorCode":null,"errorMessage":"timeout must be set","messagePattern":"timeout must be set","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"middleware/context_timeout.go","lineNumber":40,"sourceCode":"\t// Timeout configures a timeout for the middleware\n\tTimeout time.Duration\n}\n\n// ContextTimeout returns a middleware which returns error (503 Service Unavailable error) to client\n// when underlying method returns context.DeadlineExceeded error.\nfunc ContextTimeout(timeout time.Duration) echo.MiddlewareFunc {\n\treturn ContextTimeoutWithConfig(ContextTimeoutConfig{Timeout: timeout})\n}\n\n// ContextTimeoutWithConfig returns a Timeout middleware with config.\nfunc ContextTimeoutWithConfig(config ContextTimeoutConfig) echo.MiddlewareFunc {\n\treturn toMiddlewareOrPanic(config)\n}\n\n// ToMiddleware converts Config to middleware.\nfunc (config ContextTimeoutConfig) ToMiddleware() (echo.MiddlewareFunc, error) {\n\tif config.Timeout == 0 {\n\t\treturn nil, errors.New(\"timeout must be set\")\n\t}\n\tif config.Skipper == nil {\n\t\tconfig.Skipper = DefaultSkipper\n\t}\n\tif config.ErrorHandler == nil {\n\t\tconfig.ErrorHandler = func(c *echo.Context, err error) error {\n\t\t\tif err != nil && errors.Is(err, context.DeadlineExceeded) {\n\t\t\t\treturn echo.ErrServiceUnavailable.Wrap(err)\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn func(next echo.HandlerFunc) echo.HandlerFunc {\n\t\treturn func(c *echo.Context) error {\n\t\t\tif config.Skipper(c) {\n\t\t\t\treturn next(c)\n\t\t\t}","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/labstack/echo/blob/05489dc1730161df26b72d1ae2a3ba6fb8178fc7/middleware/context_timeout.go#L22-L58","documentation":"Returned by ContextTimeoutConfig.ToMiddleware when config.Timeout is the zero value (0). The middleware needs a real deadline to derive a context.WithTimeout; a zero duration would expire immediately and is treated as 'unset'. Because ContextTimeoutWithConfig routes through toMiddlewareOrPanic, this surfaces as a panic at server startup unless you call ToMiddleware directly.","triggerScenarios":"Calling ContextTimeoutWithConfig(ContextTimeoutConfig{}) without setting Timeout, calling ContextTimeout(0), or constructing the config and forgetting the Timeout field (its zero value is 0).","commonSituations":"Developer copies a config struct and deletes the Timeout line; reading the timeout from an env var that is empty so time.ParseDuration is skipped, leaving Timeout at 0; or refactoring from ContextTimeout(30*time.Second) to the WithConfig form and omitting the field.","solutions":["Set config.Timeout to a positive time.Duration, e.g. ContextTimeoutConfig{Timeout: 30 * time.Second}.","Prefer the shorthand ContextTimeout(30 * time.Second) when you only need the timeout.","If loading the duration dynamically, guard it: if d <= 0, fall back to a sane default or fail config loading explicitly.","Call config.ToMiddleware() instead of ContextTimeoutWithConfig if you want the error returned rather than panicked."],"exampleFix":"// before\nm := middleware.ContextTimeoutWithConfig(middleware.ContextTimeoutConfig{\n    ErrorHandler: myHandler,\n})\n// after\nm := middleware.ContextTimeoutWithConfig(middleware.ContextTimeoutConfig{\n    Timeout:      30 * time.Second,\n    ErrorHandler: myHandler,\n})","handlingStrategy":"validation","validationCode":"func contextTimeoutMiddleware(timeout time.Duration, eh func(*echo.Context, error) error) (echo.MiddlewareFunc, error) {\n    cfg := middleware.ContextTimeoutConfig{Timeout: timeout, ErrorHandler: eh}\n    if cfg.Timeout <= 0 {\n        return nil, errors.New(\"ContextTimeout requires a positive Timeout\")\n    }\n    return cfg.ToMiddleware()\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass a positive time.Duration to ContextTimeout or set Timeout in the config.","If the timeout comes from config/env, validate it is > 0 before wiring the middleware.","Prefer cfg.ToMiddleware() over ContextTimeoutWithConfig(cfg) in wiring code so config errors return instead of panicking."],"tags":["middleware","context-timeout","config","panic","startup"],"analyzedSha":"05489dc1730161df26b72d1ae2a3ba6fb8178fc7","analyzedAt":"2026-08-04T21:32:47.783Z","schemaVersion":2}