{"record":{"id":"ac1d2950660f2e93","repo":"PrefectHQ/fastmcp","slug":"amount-must-be-at-least-1","errorCode":null,"errorMessage":"Amount must be at least 1","messagePattern":"Amount must be at least 1","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/server/dependencies.py","lineNumber":1194,"sourceCode":"\n    @property\n    def total(self) -> int:\n        return self._total\n\n    @property\n    def message(self) -> str | None:\n        return self._message\n\n    async def set_total(self, total: int) -> None:\n        \"\"\"Set the total/target value for progress tracking.\"\"\"\n        if total < 1:\n            raise ValueError(\"Total must be at least 1\")\n        self._total = total\n\n    async def increment(self, amount: int = 1) -> None:\n        \"\"\"Atomically increment the current progress value.\"\"\"\n        if amount < 1:\n            raise ValueError(\"Amount must be at least 1\")\n        if self._current is None:\n            self._current = amount\n        else:\n            self._current += amount\n\n    async def set_message(self, message: str | None) -> None:\n        \"\"\"Update the progress status message.\"\"\"\n        self._message = message\n\n\nclass Progress(Dependency[\"Progress\"]):\n    \"\"\"Progress dependency that works in both server and worker contexts.\n\n    In a Docket worker, delegates to the execution's Redis-backed progress\n    (observable across processes). Otherwise, uses in-memory tracking.\n\n    The shared default instance acts as a stateless factory — ``__aenter__``\n    creates a fresh ``Progress`` per invocation so concurrent tasks never","sourceCodeStart":1176,"sourceCodeEnd":1212,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/server/dependencies.py#L1176-L1212","documentation":"Progress.increment() validates that each increment amount is a positive integer (>= 1) and raises ValueError otherwise. Increments of 0 or negative values are rejected because progress must monotonically advance toward the total.","triggerScenarios":"Calling `await progress.increment(0)`, `await progress.increment(-1)`, or passing a computed amount (e.g. a batch size or loop step) that is 0 or negative.","commonSituations":"Batch loops where the final batch is empty (batch_size becomes 0); arithmetic on dynamic step sizes; passing a variable that was never initialized.","solutions":["Ensure the amount passed is >= 1; skip the call when the computed step is 0","Clamp with `max(1, amount)` if a minimum step makes sense for your logic","Restructure loops so increment is only called once per unit of actual work"],"exampleFix":"// before\nstep = len(batch)\nawait progress.increment(step)  # ValueError on empty batch\n// after\nif batch:\n    await progress.increment(len(batch))","handlingStrategy":"validation","validationCode":"if not isinstance(amount, int) or amount < 1:\n    amount = max(1, int(amount or 1))  # or skip the increment\nawait progress.increment(amount)","typeGuard":null,"tryCatchPattern":"try:\n    await progress.increment(step)\nexcept ValueError:\n    pass  # zero/negative step: no progress to report","preventionTips":["Guard batch loops: only increment when the batch is non-empty","Never pass 0 to signal 'no change' — just don't call increment","Initialize step-size variables before the loop","Prefer increment() with default amount=1 for per-item loops"],"tags":["progress","validation","fastmcp"],"backgroundTag":"invalid-progress-value","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}