Skip to content

fix(safe-synthesizer): fail fast with a clear error on non-tabular input#860

Merged
marcusds merged 2 commits into
mainfrom
safe-synthesizer-tabular-input-validation/mschwab
Jul 24, 2026
Merged

fix(safe-synthesizer): fail fast with a clear error on non-tabular input#860
marcusds merged 2 commits into
mainfrom
safe-synthesizer-tabular-input-validation/mschwab

Conversation

@marcusds

@marcusds marcusds commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Summary

A Safe Synthesizer job whose input fileset has nested list/dict columns (e.g. function-calling JSONL like xlam-function-calling-60k) crashed deep inside the library's preflight with an opaque, unactionable error:

preflight.check_crash: TypeError: unhashable type: 'list'
nemo_safe_synthesizer.errors.ParameterError: Pre-flight check failed with 1 error(s)

Root cause: the library's ConstantColumnCheck runs data[col].dropna().nunique(), which can't hash list-valued cells. Safe Synthesizer is a tabular synthesizer, so nested columns are never valid input — but nothing told the user that.

Change

Validate the loaded DataFrame in run_config() (the common chokepoint for both platform and local runs) before handing it to SafeSynthesizer, and raise a ParameterError that names the offending columns and explains the requirement:

Input data is not flat tabular: column(s) tools, metadata contain nested
list/dict values. Safe Synthesizer expects one scalar value per cell —
flatten these columns or serialize them to strings (e.g. JSON) before running.

Only object-dtype columns are scanned (numeric/bool are skipped), so the check is cheap.

Notes

  • Raises the library's own ParameterError so it surfaces the same way as other bad-input errors.
  • Does not attempt to synthesize nested data — that's out of scope for a tabular synthesizer; this just replaces a cryptic crash with a clear, actionable message.
  • The underlying ConstantColumnCheck crash is a latent bug in nemo_safe_synthesizer 0.1.7 (it should guard unhashable columns like its sibling checks do) — worth a separate upstream report.
  • Unrelated to the runtime-setup dependency fix in fix(safe-synthesizer): repair runtime setup dependency resolution #856.
  • 3 pre-existing ty diagnostics in this file (lines 220/416/440) are untouched by this change and present on main.

Test

test_validate_flat_tabular_data_rejects_nested_columns (raises naming the columns) and test_validate_flat_tabular_data_allows_flat_columns (flat data passes). Full test_local_run.py suite green.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Added early validation for tabular input data.
    • Inputs containing nested lists, dictionaries, or sets now receive a clear error identifying the affected columns and recommending flattening or serialization.
    • Flat, scalar-based tabular data continues to process normally.

A job whose fileset has nested list/dict columns (e.g. function-calling
JSONL like xlam-function-calling-60k) crashed deep inside the library's
preflight with an opaque `preflight.check_crash: TypeError: unhashable
type: 'list'` — the ConstantColumnCheck calls `nunique()`, which cannot
hash list-valued cells.

Validate the loaded DataFrame in `run_config` before handing it to the
SafeSynthesizer and raise a `ParameterError` naming the offending columns
and explaining that flat tabular data is required. Safe Synthesizer is a
tabular synthesizer, so nested columns are never valid input.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Signed-off-by: mschwab <[email protected]>
@github-actions github-actions Bot added the fix label Jul 23, 2026
@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor
Suite Lines Covered Line Rate Branch Rate
Unit Tests 27140/34858 77.9% 62.1%
Integration Tests 15925/33570 47.4% 19.9%

@marcusds
marcusds marked this pull request as ready for review July 23, 2026 20:40
@marcusds
marcusds requested review from a team as code owners July 23, 2026 20:40
@marcusds marcusds self-assigned this Jul 23, 2026
@marcusds
marcusds requested a review from mckornfield July 23, 2026 20:40
@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Safe Synthesizer validates loaded DataFrames for nested values in object columns before synthesis. Invalid columns raise ParameterError; flat and nested inputs are covered by unit tests.

Changes

Flat tabular validation

Layer / File(s) Summary
Validation and test coverage
plugins/nemo-safe-synthesizer/src/nemo_safe_synthesizer_plugin/tasks/safe_synthesizer/__main__.py, plugins/nemo-safe-synthesizer/tests/unit/test_local_run.py
_validate_flat_tabular_data detects list, dictionary, and set values, run_config invokes it before synthesis, and tests cover rejection and acceptance cases.

Suggested reviewers: matthewgrossman, mckornfield

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Accurately summarizes the main change: early validation with a clearer error for nested Safe Synthesizer input.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch safe-synthesizer-tabular-input-validation/mschwab

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
plugins/nemo-safe-synthesizer/tests/unit/test_local_run.py (1)

71-91: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover the run_config() integration path.

These tests call the private validator directly, so they would still pass if the new call at __main__.py Line 321 were removed. Add a regression test that passes nested data through run_config() and verifies ParameterError is raised before Safe Synthesizer runs.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/nemo-safe-synthesizer/tests/unit/test_local_run.py` around lines 71 -
91, Extend the tests around _validate_flat_tabular_data with a run_config()
integration regression test that supplies nested tabular data, asserts
task_main.ParameterError, and verifies Safe Synthesizer is not invoked. Exercise
the public run_config() path rather than calling the private validator directly,
using the existing test helpers and mocking conventions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@plugins/nemo-safe-synthesizer/tests/unit/test_local_run.py`:
- Around line 71-91: Extend the tests around _validate_flat_tabular_data with a
run_config() integration regression test that supplies nested tabular data,
asserts task_main.ParameterError, and verifies Safe Synthesizer is not invoked.
Exercise the public run_config() path rather than calling the private validator
directly, using the existing test helpers and mocking conventions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 0228e1fb-88a0-4c7c-8e5e-30ec190b9792

📥 Commits

Reviewing files that changed from the base of the PR and between 26319c9 and 0cb6bf7.

📒 Files selected for processing (2)
  • plugins/nemo-safe-synthesizer/src/nemo_safe_synthesizer_plugin/tasks/safe_synthesizer/__main__.py
  • plugins/nemo-safe-synthesizer/tests/unit/test_local_run.py

@marcusds
marcusds enabled auto-merge July 24, 2026 19:46
@marcusds
marcusds added this pull request to the merge queue Jul 24, 2026
Merged via the queue into main with commit 9fa8f2a Jul 24, 2026
60 checks passed
@marcusds
marcusds deleted the safe-synthesizer-tabular-input-validation/mschwab branch July 24, 2026 19:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants