{"record":{"id":"39515653cd723ae8","repo":"PrefectHQ/fastmcp","slug":"total-must-be-at-least-1","errorCode":null,"errorMessage":"Total must be at least 1","messagePattern":"Total must be at least 1","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/server/dependencies.py","lineNumber":1188,"sourceCode":"    ) -> None:\n        pass\n\n    @property\n    def current(self) -> int | None:\n        return self._current\n\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.","sourceCodeStart":1170,"sourceCodeEnd":1206,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/server/dependencies.py#L1170-L1206","documentation":"The Progress dependency's set_total() validates that the reported total/target is at least 1 and raises ValueError otherwise. Progress in MCP is a counter that starts at 1-based values, so a total of 0 or negative is meaningless and would produce broken progress notifications.","triggerScenarios":"Calling `await progress.set_total(0)` or `await progress.set_total(-5)` (or a computed total that evaluates to 0, e.g. len of an empty list) inside a tool handler.","commonSituations":"Computing the total from a dynamically sized collection (empty items list); initializing progress before knowing the work size; off-by-one or uninitialized counter variables.","solutions":["Ensure the computed total is >= 1 before calling set_total (e.g. `max(1, len(items))` or skip set_total when there is no work)","Guard: only call set_total when you actually have items to process","If the work size is unknown upfront, avoid set_total and just use increment/report_progress"],"exampleFix":"// before\ntotal = len(items)\nawait progress.set_total(total)  # ValueError when items == []\n// after\nif items:\n    await progress.set_total(len(items))","handlingStrategy":"validation","validationCode":"if not isinstance(total, int) or total < 1:\n    raise ValueError(f'total must be a positive int, got {total!r}')\nawait progress.set_total(total)","typeGuard":null,"tryCatchPattern":"try:\n    await progress.set_total(total)\nexcept ValueError:\n    logger.warning(f'ignoring invalid progress total {total!r}')","preventionTips":["Clamp computed totals with max(1, n)","Skip set_total for empty workloads","Never pass floats or bools (bool is an int — True==1 passes, False==0 raises)","Default totals to len(items) only after confirming items is non-empty"],"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"}