{"record":{"id":"8bb87755dbca0f69","repo":"iflytek/astron-agent","slug":"when-mode-2-update-or-mode-4-delete-cases-cannot-be-empty","errorCode":null,"errorMessage":"When mode=2 (UPDATE) or mode=4 (DELETE), cases cannot be empty.","messagePattern":"When mode=2 \\(UPDATE\\) or mode=4 \\(DELETE\\), cases cannot be empty\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"core/workflow/engine/nodes/pgsql/pgsql_node.py","lineNumber":145,"sourceCode":"        if mode in (1, 2, 3, 4) and (v is None or v.strip() == \"\"):\n            raise ValueError(f\"When mode={mode}, tableName is required.\")\n        return v\n\n    @field_validator(\"cases\", mode=\"after\")\n    def _check_cases_for_update_delete(\n        cls, v: List[Case], info: ValidationInfo\n    ) -> List[Case]:\n        \"\"\"\n        Check if the cases are valid for the given mode.\n\n        :param v: Cases list\n        :param info: ValidationInfo\n        :return: Cases list\n        :raises ValueError: If the cases are invalid\n        \"\"\"\n        mode = info.data.get(\"mode\")\n        if mode in (2, 4) and not v:\n            raise ValueError(\n                \"When mode=2 (UPDATE) or mode=4 (DELETE), cases cannot be empty.\"\n            )\n        return v\n\n    @property\n    def run_s(self) -> WorkflowNodeExecutionStatus:\n        \"\"\"Get the success execution status.\n\n        :return: SUCCEEDED status for successful operations\n        \"\"\"\n        return WorkflowNodeExecutionStatus.SUCCEEDED\n\n    @property\n    def run_f(self) -> WorkflowNodeExecutionStatus:\n        \"\"\"Get the failure execution status.\n\n        :return: FAILED status for failed operations\n        \"\"\"","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/core/workflow/engine/nodes/pgsql/pgsql_node.py#L127-L163","documentation":"Pydantic validator on the `cases` field. UPDATE (mode=2) and DELETE (mode=4) build a WHERE clause from `cases`; with an empty cases list the statement would have no WHERE condition, which is unsafe, so the model rejects construction with a ValueError (pydantic ValidationError).","triggerScenarios":"Constructing PgsqlNodeData with mode=2 or mode=4 and `cases` set to an empty list.","commonSituations":"Author configures an UPDATE/DELETE node but never adds a condition row; frontend clears conditions on mode switch; imported workflow template with zero conditions.","solutions":["Add at least one Case (column, operator, value) to `cases` for UPDATE/DELETE nodes.","Switch to another mode if an unconditional operation is truly intended (and write explicit SQL in CUSTOM mode after reviewing the risk).","Update the workflow editor to require >=1 condition before enabling save for modes 2 and 4.","Catch and map this ValidationError to a user-facing message about missing WHERE conditions."],"exampleFix":"// before\nPgsqlNodeData(mode=4, tableName=\"users\", cases=[])\n// after\nPgsqlNodeData(mode=4, tableName=\"users\", cases=[Case(column=\"id\", operator=\"=\", value=42)])","handlingStrategy":"validation","validationCode":"def validate_cases(node_cfg: dict):\n    if node_cfg.get(\"mode\") in (2, 4) and not node_cfg.get(\"cases\"):\n        raise ValueError(\"UPDATE/DELETE require at least one case (WHERE condition)\")","typeGuard":"def has_where_cases(cfg) -> bool:\n    return cfg.mode not in (2, 4) or len(cfg.cases) > 0","tryCatchPattern":"try:\n    node_data = PgsqlNodeData(**cfg)\nexcept ValidationError as e:\n    if any(\"cases cannot be empty\" in err[\"msg\"] for err in e.errors()):\n        show_field_error(\"cases\", \"Add at least one condition for UPDATE/DELETE\")\n    raise","preventionTips":["Require at least one condition row before enabling save on UPDATE/DELETE nodes","Educate authors that unconditional UPDATE/DELETE is intentionally blocked","Re-validate conditions whenever mode changes in the editor"],"tags":["validation","pydantic","sql","safety"],"backgroundTag":"schema-validation-failed","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}