Skip to content

fix(dataset): raise a clear error on an empty dataset entry#9756

Open
he-yufeng wants to merge 2 commits into
modelscope:mainfrom
he-yufeng:fix/dataset-syntax-empty-entry
Open

fix(dataset): raise a clear error on an empty dataset entry#9756
he-yufeng wants to merge 2 commits into
modelscope:mainfrom
he-yufeng:fix/dataset-syntax-empty-entry

Conversation

@he-yufeng

Copy link
Copy Markdown
Contributor

What

DatasetSyntax.parse('') crashes with a cryptic TypeError: stat: path should be string, bytes, os.PathLike or integer, not NoneType. An empty string falls through os.path.exists('') (False) into _safe_split('', '::', ...), which returns (None, None) for an empty string, so dataset becomes None and the next os.path.exists(dataset) gets None.

An empty entry is easy to hit: swift sft --dataset "$DS1" "$DS2" where a variable is unset but quoted parses $DS2 into a stray empty string in the --dataset list. BaseArguments.load_dataset only guards if self.dataset: (the list is non-empty), not each element, and load_dataset calls DatasetSyntax.parse per entry with no filter. The crash also happens before any --strict handling, so it hard-fails regardless.

Fix

Reject an empty entry at the top of parse with a clear, actionable ValueError. Non-empty entries are unaffected.

Test

test_dataset_syntax_rejects_empty_entry asserts DatasetSyntax.parse('') raises ValueError (previously a TypeError). I confirmed the crash and the fix by extracting the parse/_safe_split logic standalone (the local checkout cannot import swift without datasets/torch); the added test runs in CI.

DatasetSyntax.parse('') fell through os.path.exists('') to _safe_split, which
returns (None, None) for an empty string, so dataset became None and the next
os.path.exists(dataset) crashed with a cryptic "stat: path should be string ...
not NoneType" TypeError. An empty entry is easy to hit from a shell invocation
like `--dataset "$DS1" "$DS2"` where a variable is unset but quoted, and it
crashes before any --strict handling. Reject an empty entry up front with a
clear, actionable ValueError instead.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request adds validation to reject empty dataset entries in DatasetSyntax.parse with a clear ValueError and includes a corresponding unit test. The review feedback suggests enhancing this validation by stripping leading and trailing whitespace to also catch whitespace-only inputs, and expanding the unit test to cover these cases.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread swift/dataset/dataset_syntax.py Outdated
Comment on lines +58 to +60
if not dataset:
raise ValueError('Received an empty dataset entry. Check `--dataset`/`--val_dataset` for a stray empty '
'string (e.g. an unset shell variable wrapped in quotes).')

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.

medium

Checking if not dataset: only handles empty strings or None, but does not handle strings that contain only whitespace (e.g., " "). A whitespace-only string will bypass this check and cause a failure later.

Additionally, stripping the dataset string at the very beginning of parse instead of only at the end (line 82) prevents potential bugs where leading or trailing whitespaces interfere with os.path.exists() checks or prefix matching (e.g., " ms::dataset" would fail to match "ms" because of the leading space).

Suggested change
if not dataset:
raise ValueError('Received an empty dataset entry. Check `--dataset`/`--val_dataset` for a stray empty '
'string (e.g. an unset shell variable wrapped in quotes).')
if isinstance(dataset, str):
dataset = dataset.strip()
if not dataset:
raise ValueError('Received an empty dataset entry. Check `--dataset`/`--val_dataset` for a stray empty '
'string (e.g. an unset shell variable wrapped in quotes).')

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 65ffb8a — strip the entry at the top of parse so a whitespace-only string collapses to empty and hits the same ValueError, and updated the message to say "empty or whitespace-only".

Comment thread tests/general/test_dataset.py Outdated
Comment on lines +82 to +91
def test_dataset_syntax_rejects_empty_entry():
import pytest

from swift.dataset.dataset_syntax import DatasetSyntax

# An empty dataset entry (e.g. an unset shell variable wrapped in quotes in a
# `--dataset "$DS1" "$DS2"` invocation) must raise a clear ValueError instead
# of crashing deep inside with a cryptic `os.path.exists(None)` TypeError.
with pytest.raises(ValueError, match='empty dataset entry'):
DatasetSyntax.parse('')

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.

medium

Expand the test to cover whitespace-only inputs (such as spaces, tabs, and newlines) to ensure they are also correctly rejected with a clear ValueError instead of causing issues down the line.

Suggested change
def test_dataset_syntax_rejects_empty_entry():
import pytest
from swift.dataset.dataset_syntax import DatasetSyntax
# An empty dataset entry (e.g. an unset shell variable wrapped in quotes in a
# `--dataset "$DS1" "$DS2"` invocation) must raise a clear ValueError instead
# of crashing deep inside with a cryptic `os.path.exists(None)` TypeError.
with pytest.raises(ValueError, match='empty dataset entry'):
DatasetSyntax.parse('')
def test_dataset_syntax_rejects_empty_entry():
import pytest
from swift.dataset.dataset_syntax import DatasetSyntax
# An empty dataset entry (e.g. an unset shell variable wrapped in quotes in a
# `--dataset "$DS1" "$DS2"` invocation) must raise a clear ValueError instead
# of crashing deep inside with a cryptic `os.path.exists(None)` TypeError.
for empty_input in ('', ' ', ' \n\t '):
with pytest.raises(ValueError, match='empty dataset entry'):
DatasetSyntax.parse(empty_input)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 65ffb8a — the test now loops over ('', ' ', '\t', '\n') and asserts each raises the clear ValueError.

Address review: strip the entry at the start of DatasetSyntax.parse so a
whitespace-only string (e.g. "   " from an unset shell variable) is rejected
with the same clear ValueError as an empty one instead of slipping through to
a failure downstream. Expand the test to cover spaces, tabs, and newlines.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant