{"record":{"id":"fbb07a5cca0a7e76","repo":"iflytek/astron-agent","slug":"when-mode-0-custom-sql-is-required-and-must-not-be-empty","errorCode":null,"errorMessage":"When mode=0 (CUSTOM), sql is required and must not be empty.","messagePattern":"When mode=0 \\(CUSTOM\\), sql is required and must not be empty\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"core/workflow/engine/nodes/pgsql/pgsql_node.py","lineNumber":111,"sourceCode":"    sql: str | None = Field(default=None, min_length=1)  # Raw SQL for CUSTOM mode\n    cases: List[Case] = Field(default_factory=list)  # WHERE conditions\n    assignmentList: List[AssignmentType] = Field(default_factory=list)  # type: ignore # Columns for SELECT/UPDATE\n    orderData: List[OrderItem] = Field(default_factory=list)  # ORDER BY configuration\n    limit: int = Field(default=0, ge=0)  # LIMIT clause for SELECT\n\n    # --- conditional validation ---\n    @field_validator(\"sql\", mode=\"after\")\n    def _check_custom_sql(cls, v: str | None, info: ValidationInfo) -> str | None:\n        \"\"\"\n        Check if the SQL is valid for CUSTOM mode.\n\n        :param v: SQL string\n        :param info: ValidationInfo\n        :return: SQL string\n        :raises ValueError: If the SQL is invalid\n        \"\"\"\n        if info.data.get(\"mode\") == 0 and (v is None or v.strip() == \"\"):\n            raise ValueError(\n                \"When mode=0 (CUSTOM), sql is required and must not be empty.\"\n            )\n        return v\n\n    @field_validator(\"tableName\", mode=\"after\")\n    def _check_table_name(cls, v: str | None, info: ValidationInfo) -> str | None:\n        \"\"\"\n        Check if the table name is valid for the given mode.\n\n        :param v: Table name string\n        :param info: ValidationInfo\n        :return: Table name string\n        :raises ValueError: If the table name is invalid\n        \"\"\"\n        mode = info.data.get(\"mode\")\n        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","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/core/workflow/engine/nodes/pgsql/pgsql_node.py#L93-L129","documentation":"Pydantic field validator on the PGSQL node's `sql` field. In CUSTOM mode (mode=0) the user must supply raw SQL; if `sql` is None or blank the model refuses to construct and raises a ValueError that surfaces as a pydantic ValidationError.","triggerScenarios":"Constructing PgsqlNodeData (or parsing the node config) with `mode: 0` and `sql` missing, empty string, or whitespace-only.","commonSituations":"Workflow author leaves the SQL editor empty in CUSTOM mode; frontend sends default/empty sql; importing a workflow JSON where the sql field was dropped.","solutions":["Provide a non-empty `sql` string in the node config when mode=0.","If the user intends table-driven operations, switch mode to 1 (INSERT), 2 (UPDATE), 3 (SELECT), or 4 (DELETE) instead of CUSTOM.","Fix the frontend/workflow editor to disable saving CUSTOM-mode nodes until SQL is entered.","Catch the pydantic ValidationError at workflow-import time and show a field-level message pointing at `sql`."],"exampleFix":"// before\nnode_data = PgsqlNodeData(mode=0, sql=\"\")\n// after\nnode_data = PgsqlNodeData(mode=0, sql=\"SELECT * FROM users WHERE id = :id\")","handlingStrategy":"validation","validationCode":"def validate_custom_sql(node_cfg: dict):\n    if node_cfg.get(\"mode\") == 0 and not (node_cfg.get(\"sql\") or \"\").strip():\n        raise ValueError(\"mode=0 requires a non-empty sql\")","typeGuard":"def has_custom_sql(cfg) -> bool:\n    return not (cfg.mode == 0 and (cfg.sql is None or not cfg.sql.strip()))","tryCatchPattern":"try:\n    node_data = PgsqlNodeData(**cfg)\nexcept ValidationError as e:\n    for err in e.errors():\n        if \"mode=0 (CUSTOM)\" in err[\"msg\"]:\n            show_field_error(\"sql\", \"Custom SQL is required\")\n    raise","preventionTips":["Require the SQL editor to be non-empty before saving CUSTOM-mode nodes","Run PgsqlNodeData validation at workflow import time, not just at runtime","Default the editor to a table mode so blank CUSTOM SQL is opt-in"],"tags":["validation","pydantic","sql","configuration"],"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"}