{"record":{"id":"23fbecf1bc114bea","repo":"microsoft/semantic-kernel","slug":"resource-constraint-is-not-set-do-not-try-to-call","errorCode":null,"errorMessage":"Resource constraint is not set. Do not try to call this method without a resource constraint.","messagePattern":"Resource constraint is not set\\. Do not try to call this method without a resource constraint\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/samples/demos/guided_conversations/guided_conversation/utils/resources.py","lineNumber":180,"sourceCode":"                        else (self.elapsed_units * 60) / elapsed_turns\n                    )\n                    time_per_turn /= 60\n                else:\n                    time_per_turn = (\n                        self.initial_seconds_per_turn if elapsed_turns == 0 else self.elapsed_units / elapsed_turns\n                    )\n                remaining_turns = self.remaining_units / time_per_turn\n\n                # Round down, unless it's less than 1, in which case round up\n                remaining_turns = math.ceil(remaining_turns) if remaining_turns < 1 else math.floor(remaining_turns)\n                return remaining_turns\n            elif self.resource_constraint.unit == ResourceConstraintUnit.TURNS:\n                return self.resource_constraint.quantity - self.turn_number\n        else:\n            self.logger.error(\n                \"Resource constraint is not set, so turns cannot be estimated using function estimate_remaining_turns\"\n            )\n            raise ValueError(\n                \"Resource constraint is not set. Do not try to call this method without a resource constraint.\"\n            )\n\n    def get_resource_instructions(self) -> tuple[str, str]:\n        \"\"\"Get the resource instructions for the conversation.\n\n        Assumes we're always using turns as the resource unit.\n\n        Returns:\n            str: the resource instructions\n        \"\"\"\n        if self.resource_constraint is None:\n            return \"\"\n\n        formatted_elapsed_resource = format_resource(self.elapsed_units, ResourceConstraintUnit.TURNS)\n        formatted_remaining_resource = format_resource(self.remaining_units, ResourceConstraintUnit.TURNS)\n\n        # if the resource quantity is anything other than 1, the resource unit should be plural (e.g. \"minutes\" instead of \"minute\")","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/samples/demos/guided_conversations/guided_conversation/utils/resources.py#L162-L198","documentation":"Raised by Resources.estimate_remaining_turns when resource_constraint is None. The method can only compute remaining turns if a ResourceConstraint (TIME or TURNS) is set; without one there is no basis for the estimate.","triggerScenarios":"Calling estimate_remaining_turns() on a Resources instance constructed without a resource_constraint; the constraint was cleared/reset to None mid-conversation.","commonSituations":"An open-ended guided conversation with no resource budget; forgetting to pass resource_constraint when building Resources; lifecycle code that nulls the constraint after exhaustion.","solutions":["Construct Resources with a non-None resource_constraint (ResourceConstraintUnit.TURNS or .TIME with a quantity).","Guard the call: if self.resource_constraint is None, skip estimate_remaining_turns.","Re-attach a resource_constraint before invoking budget-aware logic.","Use get_resource_instructions to detect the unset state and inform the model."],"exampleFix":"// before\nresources = Resources()\nresources.estimate_remaining_turns()\n\n// after\nfrom .resources import Resources, ResourceConstraint, ResourceConstraintUnit\nresources = Resources(resource_constraint=ResourceConstraint(unit=ResourceConstraintUnit.TURNS, quantity=10))\nresources.estimate_remaining_turns()","handlingStrategy":"type-guard","validationCode":"if resources.resource_constraint is None:\n    raise ValueError('Cannot estimate turns without a resource_constraint')\nresources.estimate_remaining_turns()","typeGuard":"from .resources import ResourceConstraint\n\ndef has_resource_constraint(resources) -> bool:\n    return isinstance(resources.resource_constraint, ResourceConstraint)","tryCatchPattern":"try:\n    remaining = resources.estimate_remaining_turns()\nexcept ValueError:\n    remaining = None  # unlimited conversation","preventionTips":["Always construct Resources with a ResourceConstraint for budget-bound conversations.","Guard estimate_remaining_turns with a None check.","Document that estimate_remaining_turns requires a constraint."],"tags":["guided-conversation","resources","resource-management","validation"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}