init-session.sh: a plan name with an embedded newline creates an unusable plan directory

Author: OthmanAdiCreated Sep 17, 2026Updated Sep 17, 2026
Labelsbughelp wantedgood first issue

Problem

init-session.sh "<name>" accepts a plan name that contains an embedded newline. slugify keeps the newline, mkdir -p creates a directory whose name contains it, the selector then rejects that id as an invalid slug, and init exits 1 with the directory left behind.

Scope: named-plan mode on the shell route (Linux, macOS, Git Bash) and only for a name that contains a newline, which normally comes from a script or an agent passing multi-line text as the argument. The default zero-argument root mode is not affected. The PowerShell twin already replaces newlines in Get-PlanSlug.

How to reproduce

bash
sh scripts/init-session.sh "$(printf 'line one\nline two')"
ls .planning/

Observed (Git Bash, 2026-09-17): a directory .planning/<date>-line-one<newline>line-two/ is created with the three planning files inside it, then the run prints Error: invalid plan ID. Use a named directory under .planning. and Error: could not safely update .../.planning/.active_plan. and exits 1. The pointer is not updated and the malformed directory stays behind.

Cause: slugify in skills/planning-with-files/scripts/init-session.sh pipes the name through tr '[:upper:]' '[:lower:]' and sed -e 's/[^a-z0-9]/-/g' .... sed works line by line, so the newline between the lines is never seen by the character class and survives into SLUG. PLAN_ID is then used in mkdir -p "$PLAN_DIR" before set-active-plan.sh validates it.

Suggested fix

  • Strip \r and \n in slugify before the sed step (tr -d '\r\n'), so the slug is a single line. This matches the PowerShell twin.
  • Validate PLAN_ID against the selector's slug rule before mkdir -p (the same character set set-active-plan.sh accepts), and exit 1 with a clear message when it does not match, so nothing is created for an invalid name.

A regression test can pass a name with an embedded newline and assert exit code 0 with a single-line slug, or exit 1 with no directory created, depending on which behaviour is chosen. Making the slug single-line is the friendlier option.

Origin

Found by the v3.19.0 release review (PRs #247, #248, #249). Tracked as item 5 of #250 before that issue was split into one issue per item.

Source: OthmanAdi/planning-with-files