What happened?
Exporting a workflow containing one of the four advanced sklearn trainers (KNN classifier/regressor, SVC, SVR) via POST /workflow-to-python produces a Python script that cannot be parsed when the operator's parameter table (paraList) contains two rows naming the same parameter. The emitted estimator call repeats the keyword, e.g. SVC(C = float ('1.0'),C = float ('2.0'),), and CPython raises SyntaxError: keyword argument repeated when the script is run. The export itself reports success (WorkflowToPythonSuccess); the failure only appears when the user runs the script.
What I expected: the export path refuses the duplicate the way the native path does. SklearnAdvancedBaseDesc.getParameter (used by the in-engine generatePythonCode) starts with requireDistinctParameters(paraList), whose own comment states the reason: "two rows naming one parameter emit that keyword twice and Python rejects the operator with a repeated-keyword SyntaxError. Refused here instead, where the workflow fails to compile with the parameter named." generateStandaloneCode() calls getParameterStandalone(paraList) directly and never invokes that guard, so the new export path lacks the backstop the PR itself added to the native path.
How to reproduce?
- Build a workflow JSON whose advanced trainer operator (e.g.
SklearnAdvancedSVCTrainerOpDesc) has two paraList rows with the same parameter (e.g. two rows naming C). Note the form-level uniqueAmongRows validator blocks this interactively, so construct the plan by hand or via the API; stored workflows are not schema-validated on load, and the export endpoint takes the LogicalPlanPojo with no operator-property validation.
POST the plan to /workflow-to-python.
- Run the returned script with Python: it fails with
SyntaxError: keyword argument repeated.
For comparison, running the same operator natively fails at compile time with the parameter named (the require throws inside generatePythonCode, and getPhysicalOp embeds it as #EXCEPTION DURING CODE GENERATION:).
Version/Branch
1.4.0-incubating-SNAPSHOT (main)
Commit Hash (Optional)
Verified still present at acc6dd1139d936d849e2aaa6abb288f8ef3e98ad (main tip, 2026-09-29): requireDistinctParameters is defined at SklearnAdvancedBaseDesc.scala:266 and called only from getParameter (:286); generateStandaloneCode (:447-450) still bypasses it. Introduced by #8348 (merge 5127b78bc5dfd48a904894792c299ec72ba07ab9).
What browsers are you seeing the problem on?
n/a (backend export endpoint)
Relevant log output
n/a — the exporter returns success; the SyntaxError surfaces when running the emitted script.
Suggested fix
Call requireDistinctParameters(paraList) at the top of generateStandaloneCode() (or inside getParameterStandalone), and add a standalone regression test mirroring SklearnAdvancedBaseDescSpec.scala:359 ("refuse two rows setting one parameter"), which currently exercises only the native getParameter.
What happened?
Exporting a workflow containing one of the four advanced sklearn trainers (KNN classifier/regressor, SVC, SVR) via
POST /workflow-to-pythonproduces a Python script that cannot be parsed when the operator's parameter table (paraList) contains two rows naming the same parameter. The emitted estimator call repeats the keyword, e.g.SVC(C = float ('1.0'),C = float ('2.0'),), and CPython raisesSyntaxError: keyword argument repeatedwhen the script is run. The export itself reports success (WorkflowToPythonSuccess); the failure only appears when the user runs the script.What I expected: the export path refuses the duplicate the way the native path does.
SklearnAdvancedBaseDesc.getParameter(used by the in-enginegeneratePythonCode) starts withrequireDistinctParameters(paraList), whose own comment states the reason: "two rows naming one parameter emit that keyword twice and Python rejects the operator with a repeated-keyword SyntaxError. Refused here instead, where the workflow fails to compile with the parameter named."generateStandaloneCode()callsgetParameterStandalone(paraList)directly and never invokes that guard, so the new export path lacks the backstop the PR itself added to the native path.How to reproduce?
SklearnAdvancedSVCTrainerOpDesc) has twoparaListrows with the sameparameter(e.g. two rows namingC). Note the form-leveluniqueAmongRowsvalidator blocks this interactively, so construct the plan by hand or via the API; stored workflows are not schema-validated on load, and the export endpoint takes theLogicalPlanPojowith no operator-property validation.POSTthe plan to/workflow-to-python.SyntaxError: keyword argument repeated.For comparison, running the same operator natively fails at compile time with the parameter named (the
requirethrows insidegeneratePythonCode, andgetPhysicalOpembeds it as#EXCEPTION DURING CODE GENERATION:).Version/Branch
1.4.0-incubating-SNAPSHOT (main)
Commit Hash (Optional)
Verified still present at
acc6dd1139d936d849e2aaa6abb288f8ef3e98ad(main tip, 2026-09-29):requireDistinctParametersis defined atSklearnAdvancedBaseDesc.scala:266and called only fromgetParameter(:286);generateStandaloneCode(:447-450) still bypasses it. Introduced by #8348 (merge5127b78bc5dfd48a904894792c299ec72ba07ab9).What browsers are you seeing the problem on?
n/a (backend export endpoint)
Relevant log output
n/a — the exporter returns success; the SyntaxError surfaces when running the emitted script.
Suggested fix
Call
requireDistinctParameters(paraList)at the top ofgenerateStandaloneCode()(or insidegetParameterStandalone), and add a standalone regression test mirroringSklearnAdvancedBaseDescSpec.scala:359("refuse two rows setting one parameter"), which currently exercises only the nativegetParameter.