{"record":{"id":"42b37278720c9a3a","repo":"microsoft/semantic-kernel","slug":"join-violations","errorCode":null,"errorMessage":"\" \".join(violations)","messagePattern":"\" \"\\.join\\(violations\\)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/samples/demos/guided_conversations/guided_conversation/plugins/agenda.py","lineNumber":234,"sourceCode":"                f\"The total turns allocated in the agenda must not exceed the remaining amount ({remaining_turns})\"\n            )\n            violations.append(f\"{total_resource_instruction}; but the current total is {total_resources}.\")\n\n        # In exact mode if the total resources were not exactly equal to the remaining turns\n        if (self.resource_constraint_mode == ResourceConstraintMode.EXACT) and (total_resources != remaining_turns):\n            total_resource_instruction = (\n                f\"The total turns allocated in the agenda must equal the remaining amount ({remaining_turns})\"\n            )\n            violations.append(f\"{total_resource_instruction}; but the current total is {total_resources}.\")\n\n        # Check if any item has a resource value of 0\n        if any(item[\"resource\"] <= 0 for item in items):\n            violations.append(\"All items must have a resource value greater than 0.\")\n\n        # Raise an error if any violations were found\n        if len(violations) > 0:\n            self.logger.debug(f\"Agenda update failed due to the following violations: {violations}.\")\n            raise ValueError(\" \".join(violations))\n\n    def to_json(self) -> dict:\n        agenda_dict = self.agenda.model_dump()\n        return {\n            \"agenda\": agenda_dict,\n        }\n\n    @classmethod\n    def from_json(\n        cls,\n        json_data: dict,\n        kernel: Kernel,\n        service_id: str,\n        resource_constraint_mode: ResourceConstraintMode | None,\n        max_agenda_retries: int = 2,\n    ) -> \"Agenda\":\n        agenda = cls(kernel, service_id, resource_constraint_mode, max_agenda_retries)\n        agenda.agenda.items = json_data[\"agenda\"][\"items\"]","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/samples/demos/guided_conversations/guided_conversation/plugins/agenda.py#L216-L252","documentation":"Raised by the Agenda plugin when one or more validation rules fail during an agenda update: total resource (turns) across items must equal the remaining amount, and every item must have a resource value greater than 0. All violations are collected and joined into a single ValueError message for the LLM.","triggerScenarios":"The LLM proposes an agenda whose item resource values do not sum to the remaining turns, or sets any item's resource to 0 or negative; from_json loading a malformed agenda payload.","commonSituations":"The model miscounts remaining turns; an agenda update payload is hand-crafted with wrong totals; resource_constraint changed but the agenda wasn't recomputed.","solutions":["Ensure the sum of item['resource'] across all agenda items equals the remaining turns.","Ensure every item has resource > 0.","Read the joined violation messages in the exception text — they state the expected total and which rule failed.","Recompute the agenda from the current resource_constraint rather than guessing totals."],"exampleFix":"// before\nagenda.update({\"items\": [{\"name\": \"intro\", \"resource\": 0}, {\"name\": \"body\", \"resource\": 3}]}, remaining_turns=5)\n\n// after\nagenda.update({\"items\": [{\"name\": \"intro\", \"resource\": 2}, {\"name\": \"body\", \"resource\": 3}]}, remaining_turns=5)","handlingStrategy":"validation","validationCode":"def validate_agenda(items: list[dict], remaining_turns: int) -> list[str]:\n    violations = []\n    total = sum(i.get('resource', 0) for i in items)\n    if total != remaining_turns:\n        violations.append(f'total {total} != remaining {remaining_turns}')\n    if any(i.get('resource', 0) <= 0 for i in items):\n        violations.append('all resources must be > 0')\n    return violations\nviolations = validate_agenda(items, remaining_turns)\nif violations:\n    raise ValueError(' '.join(violations))","typeGuard":"def is_valid_agenda(items: list[dict], remaining_turns: int) -> bool:\n    return (\n        len(items) > 0\n        and all(i.get('resource', 0) > 0 for i in items)\n        and sum(i['resource'] for i in items) == remaining_turns\n    )","tryCatchPattern":"try:\n    agenda.update(payload, remaining_turns=remaining)\nexcept ValueError as ex:\n    # surface violations back to the model for correction\n    corrections.append(str(ex))","preventionTips":["Compute item resources from remaining_turns rather than hardcoding.","Validate agenda payloads before update.","Feed the violation text back to the LLM as a correction."],"tags":["guided-conversation","agenda","validation","resource-management"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}