Skip to content

Fail update when the platform rejects the container change - #15

Merged
cory-salad merged 2 commits into
mainfrom
claude/update-image-rejected-5cc4ec
Oct 30, 2026
Merged

cory-salad merged 2 commits into
mainfrom
claude/update-image-rejected-5cc4ec

Conversation

@cory-salad

Copy link
Copy Markdown
Contributor

Summary

When you run container-groups update with a new image, the API accepts the change at once and then checks it before
any instance runs it. If the registry doesn't serve that image, for example a tag that doesn't exist or a private image
sent without its registry credentials, the platform drops the new version and the group keeps running the old one. The
CLI waited for the change to settle, but it only printed one warning: line on stderr, exited 0, and never showed the
platform's reason, so a failed update looked like a success. Now update treats a container change that didn't land
as an error: it exits 6 with the platform's reason, and when the image changed without credentials, the hint says a
private image needs them sent again.

Changes

  • internal/cli/intentdiff.go, groups.go: after the settle, update fails when a container change didn't land.
    Either of two signals is enough: a container field the patch named (image, command, CPU, memory, GPU classes,
    storage, an environment variable) stayed exactly where it was, or the write left a new Version N: <reason>
    description for an N above the running version. Only a new report counts, because the API keeps the old one on the
    group through later writes. The error is exit 6, kind invalid_input, with empty stdout and a message such as
    the API did not apply the container change to my-app: Version 2: Manifest Not Found.
  • When the patch changed the image without container.registry_authentication, the hint reuses create --from's
    credential advice. It is keyed on the failure, not on the registry, so it applies to Docker Hub too.
  • internal/cli/containerrejection_test.go: unit and harness tests for both signals, the stale-description case and
    the hint.
  • internal/livetest/provision_test.go: TestGroupLifecycle gains an update to a tag that doesn't exist.
  • docs/guide.md, docs/commands.md, docs/notes.md, the validation table in AGENTS.md, and a ### Fixed
    CHANGELOG entry.

Contract change

container-groups update now exits 6 (kind invalid_input, stdout empty) in a case where it used to exit 0 and print
the settled group. No new exit code or error kind; the guide's exit-code and kind tables mention the new case.

Checklist

  • just ci passes (formatting, lint, and the offline tests): run locally on Windows with Go 1.27.3, after merging
    main.
  • docs/ (and the README, if install or getting started changed) and CHANGELOG.md (under Unreleased) reflect the
    change.
  • Anything that touches an API call was exercised live, or this pull request says it was not: exercised live by
    hand on a busybox CPU group, both running and stopped, with a tag that doesn't exist. The private-image case
    wasn't reproduced live; its message comes from an earlier failure. There's no record yet of just test-live
    being run with the new TestGroupLifecycle step.

🤖 Generated with Claude Code

cory-salad and others added 2 commits October 27, 2026 15:52
`container-groups update` exited 0 when the API accepted a container change
and then dropped the new version: the group stayed on its old image, the
write-verification diff printed one `warning:` line, and the platform's
reason (`current_state.description`, e.g. "Version 2: Manifest Not Found")
was never shown. A private Docker Hub image sent without its registry
credentials fails exactly this way.

After the settle, `applyPatch` now treats a container change that did not
land as an error: exit 6 (`invalid_input`), stdout empty, the API's reason
in the message. Two signals, either enough: a container field the patch
named (image, command, cpu, memory, GPU classes, storage, an environment
variable) stayed exactly where it was, or the write left a new
"Version N: <reason>" for an N above the running version. Only a new
report counts, since the API keeps it on the group through later writes.
When the patch changed the image without `container.registry_authentication`,
the hint reuses create --from's credential advice, keyed on the failure
rather than on the registry.

Verified live on a busybox CPU group (running and stopped) with a
nonexistent tag; the live suite's TestGroupLifecycle gains the same step.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cory-salad
cory-salad requested a review from a team as a code owner October 30, 2026 19:23
@cory-salad
cory-salad merged commit fe62698 into main Oct 30, 2026
12 checks passed
@cory-salad
cory-salad deleted the claude/update-image-rejected-5cc4ec branch October 30, 2026 21:37
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.

1 participant