{"id":"e84c1e5d93983114","repo":"laravel/framework","slug":"timeout-must-be-greater-than-zero","errorCode":null,"errorMessage":"Timeout must be greater than zero.","messagePattern":"Timeout must be greater than zero\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Illuminate/Database/Query/Builder.php","lineNumber":3381,"sourceCode":"     * @return $this\n     */\n    public function sharedLock()\n    {\n        return $this->lock(false);\n    }\n\n    /**\n     * Set a query execution timeout in seconds.\n     *\n     * @param  int|null  $seconds\n     * @return $this\n     *\n     * @throws InvalidArgumentException\n     */\n    public function timeout(?int $seconds): static\n    {\n        if ($seconds !== null && $seconds <= 0) {\n            throw new InvalidArgumentException('Timeout must be greater than zero.');\n        }\n\n        $this->timeout = $seconds;\n\n        return $this;\n    }\n\n    /**\n     * Register a closure to be invoked before the query is executed.\n     *\n     * @return $this\n     */\n    public function beforeQuery(callable $callback)\n    {\n        $this->beforeQueryCallbacks[] = $callback;\n\n        return $this;\n    }","sourceCodeStart":3363,"sourceCodeEnd":3399,"githubUrl":"https://github.com/laravel/framework/blob/bd6b5437e6ad87bb49f9b426724f07a9f64e9683/src/Illuminate/Database/Query/Builder.php#L3363-L3399","documentation":"Thrown by timeout() when the supplied integer of seconds is <= 0 (and not null). The setter configures the per-query execution timeout; zero or negative durations are meaningless for SQL statement timeouts and would either no-op or be rejected by the driver. Passing null explicitly disables the timeout and is allowed.","triggerScenarios":"`->timeout(0)`, `->timeout(-1)`. Computing timeout from a config value that defaults to 0. Subtracting a large offset that goes negative: `->timeout($budget - $elapsed)`.","commonSituations":"Config-driven timeouts where the env var is unset and casts to 0; adaptive timeout budgets that go negative under load; tests passing 0 expecting 'no timeout' semantics.","solutions":["Pass a positive integer: `->timeout(30)`.","Pass null to disable: `->timeout(null)`.","Guard config-driven values: `->timeout($cfg > 0 ? $cfg : null)`.","Validate before calling: `if ($seconds !== null && $seconds <= 0) abort(400, 'bad timeout');`."],"exampleFix":"// before\n$query->timeout((int) config('app.query_timeout', 0))->get();\n// when default is 0 => Timeout must be greater than zero.\n\n// after\n$secs = (int) config('app.query_timeout', 0);\n$query->timeout($secs > 0 ? $secs : null)->get();","handlingStrategy":"validation","validationCode":"if ($seconds !== null && $seconds <= 0) {\n    $seconds = null; // or throw\n}\n$query->timeout($seconds);","typeGuard":"function isValidTimeout(?int $s): bool\n{\n    return $s === null || $s > 0;\n}","tryCatchPattern":"// Validate before calling; catching an InvalidArgumentException here adds noise.","preventionTips":["Treat 0 as 'no timeout' by mapping to null at the config layer.","Bound any adaptive timeout from below: max(1, $computed).","Unit-test the timeout helper with edge values (0, -1, null)."],"tags":["query-builder","timeout","invalid-argument"],"analyzedSha":"bd6b5437e6ad87bb49f9b426724f07a9f64e9683","analyzedAt":"2026-08-06T00:28:32.783Z","schemaVersion":2}