Skip to content

fix(run): a blank script crashes pdm run --list - #3842

Merged
frostming merged 3 commits into
pdm-project:mainfrom
VXNCXNX:fix/blank-script-list-crash
Aug 16, 2026
Merged

fix(run): a blank script crashes pdm run --list#3842
frostming merged 3 commits into
pdm-project:mainfrom
VXNCXNX:fix/blank-script-list-crash

Conversation

@VXNCXNX

@VXNCXNX VXNCXNX commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Pull Request Checklist

  • A news fragment is added in news/ describing what is new. (news/3842.bugfix.md; happy to renumber it if you would rather it carried a different number)
  • Test cases added for changed code. (test_run_show_list_of_scripts_with_blank_script in tests/cli/test_run.py)

Describe what you have changed in this PR.

What's broken

A blank script makes pdm run --list unusable.

[tool.pdm.scripts]
build = "python -V"
blank = "   "
$ pdm run --list
[IndexError]: list index out of range
WARNING: Add '-v' to see the detailed traceback

pdm run --json fails the same way. Everything else keeps working, including pdm run build, so a single blank entry takes out the listing for every other script in the file.

  File ".../pdm/cli/commands/run.py", line 460, in show_list
    task.short_description,
  File ".../pdm/cli/commands/run.py", line 154, in short_description
    fallback = f"{lines[0]}{termui.Emoji.ELLIPSIS}" if len(lines) > 1 else lines[0]
IndexError: list index out of range

The fix

lines is built by filtering blank lines out, so a whitespace-only script leaves it empty, and the else branch indexes lines[0] unconditionally.

The empty case now falls back to an empty description, which is what the listing needs: a row with a blank Description cell rather than no table at all.

╭───────┬──────┬─────────────╮
│ Name  │ Type │ Description │
├───────┼──────┼─────────────┤
│ blank │ cmd  │             │
│ build │ cmd  │ python -V   │
╰───────┴──────┴─────────────╯

short_description is the only accessor, and its three call sites are show_list for the table, as_json for --json, and the task display, so the one guard covers all three. --json now emits "help": "" for the blank script.

Scope

There is a second IndexError of the same family further down the file, on the composite path, reachable when {args} interpolates to nothing. That is a separate concern with a behaviour decision attached, so it is not in this PR.

Verification

test_run_show_list_of_scripts_with_blank_script, right after test_run_show_list_of_scripts, matching its style of asserting on rendered table rows. With the guard reverted it fails with the IndexError above.

tests/cli/test_run.py -k "composite or list_of_scripts" is 26 passed, against 25 on main. ruff check and ruff format are both clean.

No matching open issue was filed for this, I hit it with a whitespace-only script in my own pyproject.toml.

Disclosure: written with AI assistance (Claude Code). I reproduced the issue, ran the change and the verification myself.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Comment thread src/pdm/cli/commands/run.py Outdated
@VXNCXNX

VXNCXNX commented Aug 16, 2026

Copy link
Copy Markdown
Contributor Author

Good call, done. A blank script now shows <BLANK_SCRIPT> instead of an empty cell:

╭────────────┬──────┬─────────────────╮
│ test_blank │ cmd  │ <BLANK_SCRIPT>  │
│ test_cmd   │ cmd  │ flask db upgrade│
╰────────────┴──────┴─────────────────╯

The test asserts the marker rather than the empty string, so removing the branch fails it with the original IndexError rather than passing quietly. tests/cli/test_run.py is 92 passed. News fragment updated to mention the marker.

@codecov

codecov Bot commented Aug 16, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.36%. Comparing base (a50e76f) to head (0d8831d).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3842   +/-   ##
=======================================
  Coverage   88.36%   88.36%           
=======================================
  Files         121      121           
  Lines       13240    13250   +10     
  Branches     2249     2252    +3     
=======================================
+ Hits        11700    11709    +9     
+ Misses        970      969    -1     
- Partials      570      572    +2     
Flag Coverage Δ
unittests 88.25% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@frostming frostming left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Review: APPROVE ✅

The fix is correct, minimal, and safe to merge.

Bug

A blank/whitespace-only script (e.g. blank = " ") made pdm run --list and pdm run --json crash with IndexError: list index out of rangeshort_description filters blank lines, leaving lines[0] unguarded.

Fix

In Task.short_description (src/pdm/cli/commands/run.py), add a guard:

if not lines:
    fallback = "<BLANK_SCRIPT>"
else:
    fallback = ...

Single change fixes both --list and --json since both call short_description.

Verification (local)

  • tests/cli/test_run.py: 92 passed (checked out PR head 0d8831d2 in a worktree)
  • E2E: pdm run --list renders <BLANK_SCRIPT> for both " " and "" scripts; non-blank scripts unaffected
  • --json emits "help": "<BLANK_SCRIPT>"
  • Multi-line scripts still get the ellipsis () suffix

CI

All green: Pack + Testing matrix (3.10–3.15 × macOS/ubuntu/windows). mergeStateStatus: CLEAN, mergeable. Codecov: all modified lines covered, coverage unchanged.

Note

The reviewer suggestion (frostming) to mark it with <BLANK_SCRIPT> rather than an empty cell is implemented in the head commit, and the news fragment was updated accordingly.

@frostming
frostming merged commit 245fd1c into pdm-project:main Aug 16, 2026
25 checks passed
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.

2 participants