Skip to content

Fix main() panicking on os.Args[1] when invoked with no arguments (closes #29) - #38

Merged
dolph merged 1 commit into
mainfrom
claude/issue-29-main-panic
Apr 27, 2026
Merged

Fix main() panicking on os.Args[1] when invoked with no arguments (closes #29)#38
dolph merged 1 commit into
mainfrom
claude/issue-29-main-panic

Conversation

@dolph

@dolph dolph commented Apr 27, 2026

Copy link
Copy Markdown
Owner

Closes #29.

Summary

./ussher (no arguments) used to panic with runtime error: index out of range [1] with length 1 because main() accessed os.Args[1] on its very first line — the --version short-circuit — before the args-count check ten lines further down. The intended usage: ussher <username> message was unreachable for the no-args case.

Fix

Extract validateArgs(args []string) (string, error). It enforces len(args) == 2 and returns either the single arg (the username, or --version) or a typed usage error. main() calls it as its very first statement and log.Fatals on error.

-    if os.Args[1] == "--version" {
+    arg, err := validateArgs(os.Args)
+    if err != nil {
+        log.Fatal(err)
+    }
+    if arg == "--version" {
        PrintVersion()
        return
     }
     ...
-    if len(os.Args) != 2 {
-        log.Fatal("usage: ussher <username>")
-    }
-    username := os.Args[1]
+    username := arg

The downstream len(os.Args) != 2 check is now dead code and removed. The --version short-circuit, the security gates, initLog, and isValidUser sequencing are unchanged. This extraction is also a useful seam for the broader main() refactor proposed in #13 — that issue's parseArgs would build on this validateArgs.

Tests

New ussher_test.go with TestValidateArgs covering six cases:

  • bare program name (no args) → error
  • empty args slice → error
  • single arg as username → returns username
  • single arg as --version → returns --version
  • too many args (3 with username) → error
  • too many args (3 with --version) → error

Coverage 42.1% → 42.7%; tests pass under -race.

End-to-end repro

$ ./ussher
2026/04/27 20:11:26 usage: ussher <username>
$ echo $?
1

(Pre-fix: stack trace + exit 2.)

Releasing-this-thought

v1.1.0 is queued in CHANGELOG.md but not yet tagged. The new Fixed bullet lives under [Unreleased] for safety — if you want this fix in v1.1.0, move the bullet into [1.1.0] before pushing the tag; otherwise it ships in 1.1.1 / 1.2.0. Either is fine.

Test plan

  • ./build.sh green; coverage 42.7%.
  • go test -race ./... green.
  • ./ussher (no args) prints usage: ussher <username> and exits 1 (no panic).
  • ./ussher --version still prints version info.
  • ./ussher root (or any valid user) still proceeds normally.
  • ./ussher alice extra still rejected as wrong-arg-count.
  • CI shellcheck + build jobs both green on the PR.

https://claude.ai/code/session_013HnepY8MhhxrJJjE5ysW47


Generated by Claude Code

Closes #29.

`./ussher` (no arguments) used to panic with a Go runtime "index out
of range" trace because main() accessed os.Args[1] on the very first
line - the `--version` short-circuit - before the args-count check
ten lines further down had a chance to fire. The clean
"usage: ussher <username>" message that check was supposed to
produce was unreachable for the no-args case.

Extracts the arg-validation into validateArgs(args []string) (string,
error), which returns the single argument or a typed usage error.
main() calls it as the very first statement and log.Fatal()s on
error, so bare invocation now prints "usage: ussher <username>" and
exits 1 cleanly. The downstream args-count check is removed (now
dead code). The --version short-circuit, security gates, initLog,
and isValidUser sequencing are unchanged.

The extraction is also a useful seam for the broader main() refactor
proposed in #13 - parseArgs there would build on validateArgs here.

Tests in a new ussher_test.go cover six cases: bare program name,
empty args slice, single-arg-as-username, single-arg-as-version,
too-many-args (with and without --version). Coverage 42.1% -> 42.7%.
End-to-end repro: `./ussher` now prints
"2026/04/27 20:11:26 usage: ussher <username>" to stderr and exits 1
instead of crashing.

CHANGELOG bullet under [Unreleased] / Fixed. If the maintainer wants
this fix in the (yet-untagged) v1.1.0, the bullet can be moved into
[1.1.0] before the tag push; otherwise it ships in 1.1.1 / 1.2.0.
@dolph
dolph merged commit 2337b45 into main Apr 27, 2026
4 checks passed
@dolph
dolph deleted the claude/issue-29-main-panic branch April 27, 2026 20:29
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.

main() panics on os.Args[1] when invoked with no arguments

2 participants