Skip to content

fix(pod): remove --stop-after and --terminate-after - #330

Merged
justinwlin merged 1 commit into
mainfrom
justinlin/con-1258-enforce-runpodctl-stop-after-and-terminate-after-timers
Aug 27, 2026
Merged

fix(pod): remove --stop-after and --terminate-after#330
justinwlin merged 1 commit into
mainfrom
justinlin/con-1258-enforce-runpodctl-stop-after-and-terminate-after-timers

Conversation

@justinwlin

@justinwlin justinwlin commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

--stop-after and --terminate-after never worked. Both are removed.

Part of CON-1258, which stays open: this removes the broken surface, it does not fix the feature. runpod/RunPod#5718 is the backend fix that makes the deadline actually fire, and runpodctl#331 restores the flags with validation once it lands.

Why

The flags were forwarded to podFindAndDeployOnDemand as stopAfter / terminateAfter. The API accepts both as valid input and then does not act on them: the pod keeps running, and billing, past the deadline.

The value is also write-only. It is not readable on the Pod type and does not exist in REST v2 at all, so the CLI cannot confirm the timer landed, and cannot detect afterwards that it did not fire.

Three further problems, all moot once the flag is gone:

  • CPU pods dropped it silently — they are created over REST v2, which has no scheduling field.
  • Past timestamps were accepted; the deadline simply never arrived.
  • The documented duration form (1h, 24h, 7d) was rejected by the GraphQL DateTime scalar, leaking the raw scalar error. Only RFC 3339 was ever sent successfully.

Nothing a client can do makes the timer fire, and a flag that silently costs money is worse than no flag.

What changed

Both flags are deleted. Passing one is a usage error:

$ runpodctl pod create --image ubuntu:22.04 --stop-after 2h
{"error":"unknown flag: --stop-after","code":"usage_error"}

They no longer appear in --help or the generated docs, and StopAfter / TerminateAfter are dropped from CreatePodGQLInput. internal/duration is untouched — duration.Parse still backs --since and --wait-timeout.

Release notes

Breaking. runpodctl pod create --stop-after and --terminate-after are removed. Scripts passing either now fail with unknown flag and a non-zero exit instead of creating a pod on a timer that never fired. There is no replacement until the backend enforces the deadline; until then, stop or terminate the pod explicitly.

Evidence

Two GPU pods created against production with stopAfter roughly four minutes out. Both stayed RUNNING past the deadline, with no state change and no error. Deleted manually afterwards.

Pod stopAfter Last observation desiredStatus
mqb8yey2sq8qka 16:45:46Z 16:49:34Z RUNNING
bdwcl5lzqwqny0 16:48:35Z 16:49:34Z RUNNING

go build ./... and go test ./... green.

@justinwlin
justinwlin force-pushed the justinlin/con-1258-enforce-runpodctl-stop-after-and-terminate-after-timers branch from 2cf39ea to 9c44819 Compare August 26, 2026 19:19
@justinwlin justinwlin changed the title fix(pod): validate --stop-after and --terminate-after fix(pod): remove --stop-after and --terminate-after Aug 26, 2026
Both flags were forwarded to podFindAndDeployOnDemand, which accepts
stopAfter/terminateAfter and never acts on them: the pod keeps running,
and billing, past the deadline. The value is also not readable back from
the Pod type or REST v2, so the cli cannot detect the failure after the
fact either.

Nothing a client can do makes the timer fire, and a flag that silently
costs money is worse than no flag, so both are gone. Passing one is now
a usage error.

Also drops StopAfter/TerminateAfter from CreatePodGQLInput and
duration.ParseDeadline, which had no other caller.
@justinwlin
justinwlin force-pushed the justinlin/con-1258-enforce-runpodctl-stop-after-and-terminate-after-timers branch from 9c44819 to d381563 Compare August 26, 2026 19:28
@justinwlin
justinwlin marked this pull request as ready for review August 26, 2026 19:37

@lukepiette lukepiette 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.

LGTM. Deletion-only change removing two flags that were silently ignored server-side while the pod kept billing — failing loudly beats silently costing money.

What I verified:

  • No leftovers. Grepped the head branch for stopAfter, terminateAfter, stop-after, terminate-after, and ParseDeadline across Go and Markdown — zero matches. Removal is complete, including the generated docs.
  • Builds and tests pass. go build ./... and the full test suite are green on the branch locally.
  • The rationale holds. The field is write-only with no REST v2 equivalent, so the CLI genuinely can't verify or enforce the timer, and the PR's production evidence shows the API ignores it.

Two notes, neither blocking:

  1. Stale description: the body says duration.ParseDeadline was dropped, but it doesn't exist on main and no duration file is in the diff (only duration.Parse exists, still used by --since / --wait-timeout). Worth correcting the description before merge.
  2. Breaking CLI change: scripts passing --stop-after will now hard-fail with unknown flag. Right behavior, but deserves a release-notes line. And since auto-stop is a genuinely useful capability, confirm the backend ticket (CON-1258) stays open rather than closing with this PR.

🤖 Reviewed with Claude Code

@justinwlin
justinwlin merged commit 51ca7f0 into main Aug 27, 2026
1 check passed
@justinwlin
justinwlin deleted the justinlin/con-1258-enforce-runpodctl-stop-after-and-terminate-after-timers branch August 27, 2026 22:51
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