{"record":{"id":"b567a24402b5d2ca","repo":"crewAIInc/crewAI","slug":"seconds-must-be-zero-or-greater-got-seconds-g","errorCode":null,"errorMessage":"seconds must be zero or greater, got {seconds:g}.","messagePattern":"seconds must be zero or greater, got (.+?)\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"lib/crewai-tools/src/crewai_tools/tools/wait_tool/wait_tool.py","lineNumber":177,"sourceCode":"\n        ``BaseTool.run`` skips ``args_schema`` validation when called with\n        positional arguments, so the bounds are enforced here too rather than\n        left to ``time.sleep`` to reject. Infinity is a valid request: it clamps\n        to the cap like any other oversized wait.\n\n        Args:\n            seconds: The requested wait duration.\n\n        Returns:\n            A tuple of the duration to actually wait and whether it was capped.\n\n        Raises:\n            ValueError: If ``seconds`` is negative or not a number.\n        \"\"\"\n        if math.isnan(seconds):\n            raise ValueError(\"seconds must be a number, got NaN.\")\n        if seconds < 0:\n            raise ValueError(f\"seconds must be zero or greater, got {seconds:g}.\")\n        if seconds > self.max_seconds:\n            return self.max_seconds, True\n        return seconds, False\n\n    def _format_result(\n        self, waited: float, requested: float, reason: str | None\n    ) -> str:\n        \"\"\"Describe the completed wait back to the model.\n\n        Args:\n            waited: The duration actually waited.\n            requested: The duration the model asked for.\n            reason: Optional note on what is being waited for.\n\n        Returns:\n            A summary of how long was waited and whether the request was capped.\n        \"\"\"\n        parts = [f\"Waited {_format_seconds(waited)}.\"]","sourceCodeStart":159,"sourceCodeEnd":195,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/crewai-tools/src/crewai_tools/tools/wait_tool/wait_tool.py#L159-L195","documentation":"WaitTool's duration validator rejects negative wait times. A negative duration is meaningless for sleep() and usually signals a sign error or misparsed value upstream, so it fails fast with a message echoing the offending number (%g formatting).","triggerScenarios":"An agent or caller invoking wait with a negative number (wait(seconds=-5)), or arithmetic that yields a negative value such as end_time - start_time with the operands swapped, or '-30' parsed from model output.","commonSituations":"LLMs emitting negative durations in tool calls; time-delta math where a countdown goes below zero; timezone/DST arithmetic producing negative intervals.","solutions":["Clamp to zero (or a small positive floor) before calling: seconds = max(0.0, seconds).","Fix the sign logic upstream (swap operands of the subtraction, use abs() only if direction is irrelevant).","Add a minimum/maximum constraint in the tool description so the model is steered to non-negative values."],"exampleFix":"# before\nseconds = end - start  # accidentally negative\ntool.run(seconds=seconds)  # ValueError: must be zero or greater\n\n# after\nseconds = max(0.0, end - start)\ntool.run(seconds=seconds)","handlingStrategy":"validation","validationCode":"def clamp_seconds(v) -> float:\n    try:\n        f = float(v)\n    except (TypeError, ValueError):\n        return 0.0\n    return max(0.0, f)\n\n# seconds = clamp_seconds(raw) before WaitTool","typeGuard":"import math\n\ndef is_non_negative_number(v) -> bool:\n    try:\n        f = float(v)\n    except (TypeError, ValueError):\n        return False\n    return not math.isnan(f) and f >= 0","tryCatchPattern":"try:\n    tool.run(seconds=raw)\nexcept ValueError as e:\n    if 'zero or greater' in str(e):\n        tool.run(seconds=abs(float(raw)))  # or 0.0; log the sign error\n    else:\n        raise","preventionTips":["Clamp durations with max(0.0, x) at the caller boundary.","Check time-delta arithmetic for operand order before feeding results to waits.","Constrain the tool schema/description to non-negative numbers to steer the model."],"tags":["validation","numeric","sign-error","llm-output"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}