From f662a574f95c7170a9b7f84cae1e13f8b152e262 Mon Sep 17 00:00:00 2001 From: Alex Kroman Date: Thu, 11 Jun 2026 17:40:51 -0700 Subject: [PATCH] Fix transcribe treating empty source as a directory scan `assembly transcribe ""` silently batch-walked the working directory: an empty string fell through the `source is None` guard in expand_sources, and since Path("") resolves to ".", it was treated as "batch this directory" and recursively rglob'd every audio file under cwd. With a valid key that would upload arbitrary local audio. Treat an empty source like a missing one (`not source`) so it stays on the single-source path, where it correctly reads as "Provide an audio path or URL." Co-Authored-By: Claude Opus 4.8 (1M context) --- aai_cli/transcribe_batch.py | 5 ++++- tests/test_transcribe_batch_sources.py | 18 +++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/aai_cli/transcribe_batch.py b/aai_cli/transcribe_batch.py index 358f4085..adcfe62b 100644 --- a/aai_cli/transcribe_batch.py +++ b/aai_cli/transcribe_batch.py @@ -73,7 +73,10 @@ def expand_sources(source: str | None, *, from_stdin: bool, sample: bool) -> lis """ if from_stdin: return _stdin_sources(source, sample=sample) - if source is None or sample or source == "-" or source.startswith(_URL_PREFIXES): + if not source or sample or source == "-" or source.startswith(_URL_PREFIXES): + # `not source` also catches "": Path("") is ".", which would otherwise scan the + # whole working directory. An empty source belongs on the single-source path, + # where it reads as "Provide an audio path or URL." return None path = Path(source) if path.is_dir(): diff --git a/tests/test_transcribe_batch_sources.py b/tests/test_transcribe_batch_sources.py index d3c1f0fc..e387c82f 100644 --- a/tests/test_transcribe_batch_sources.py +++ b/tests/test_transcribe_batch_sources.py @@ -152,11 +152,27 @@ def test_from_stdin_rejects_sample(): assert "--from-stdin reads sources from stdin" in result.output -@pytest.mark.parametrize("source", ["-", "https://example.com/a.mp3", None]) +@pytest.mark.parametrize("source", ["-", "https://example.com/a.mp3", None, ""]) def test_non_batch_sources_return_none(source): + # An empty string is not a batch source: Path("") resolves to ".", so without + # this guard it would silently scan the whole working directory recursively. assert transcribe_batch.expand_sources(source, from_stdin=False, sample=False) is None +def test_empty_source_argument_does_not_batch_the_working_directory(monkeypatch): + _auth() + # A loud canary: if "" ever reaches directory scanning again, every audio file + # under cwd gets queued. rglob must never run for an empty source. + monkeypatch.setattr( + transcribe_batch.Path, + "rglob", + lambda self, pattern: pytest.fail("empty source must not scan the directory"), + ) + result = runner.invoke(app, ["transcribe", ""]) + assert result.exit_code == 2 + assert "Provide an audio path or URL." in result.output + + def test_sample_returns_none_even_without_source(): assert transcribe_batch.expand_sources(None, from_stdin=False, sample=True) is None