Skip to content

fix(templates): a refusal from Steam is not a failed installation - #122

Closed
aaldersondev wants to merge 1 commit into
mainfrom
fix/steam-install-retry
Closed

fix(templates): a refusal from Steam is not a failed installation#122
aaldersondev wants to merge 1 commit into
mainfrom
fix/steam-install-retry

Conversation

@aaldersondev

Copy link
Copy Markdown
Contributor

What happened

An install of app 4020 ended like this, and the panel reported Installation failed (code 8):

Connecting anonymously to Steam Public...OK
Waiting for client config...OK
Waiting for user info...OK
ERROR! Failed to install app '4020' (Missing configuration)

What it was — measured, not reasoned

Reproduced on the same machine in a fresh debian:bookworm-slim container, with the template's exact command and 31 GB free: same message, exit 8, before a byte of depot. The same line, on the same machine, in another fresh container ten minutes later, downloaded all 6.87 GB.

Steam had not handed out the app's configuration. Nothing on the node decides that, and the template's command is right.

The neighbouring hypothesis was tested and ruled out: given only 1.9 GB for a 6.87 GB depot, SteamCMD says state is 0x202, not Missing configuration. Two different failures with two different fixes, and the difference is not guessable from the text.

What changes

The depot is fetched up to three times. Three and not thirty: a real failure — a wrong app id, a full volume — fails the same way every time, and is better reported in a minute than in an hour. A retry costs little either, since Steam keeps what it has already staged under steamapps/downloading.

When it does give up, it names which of three things happened:

SteamCMD says What it means
Missing configuration Steam refused. Nothing local — reinstall in a few minutes.
state is 0x202 Out of room; the install wants about twice the finished size free.
No subscription The app id is not anonymously installable — a client's id, most often.

Anything else prints SteamCMD's own last words, as before.

tee rather than a redirection, so the operator goes on watching the download in their console — an install that goes silent for six gigabytes looks stuck — while the last attempt is kept for the diagnosis.

Scope and tests

The script is shared by every Source template, so Garry's Mod and its neighbour both get it.

Four assertions in the catalogue suite, and the generated loop was exercised outside it against a fake steamcmd failing zero, one, two and three times: succeeds on attempts 1, 2 and 3, gives up on the fourth refusal with exit 1 and the right diagnosis. Each of the three branches was checked against the message that triggers it.

🤖 Generated with Claude Code

An install of app 4020 ended on

  Connecting anonymously to Steam Public...OK
  Waiting for user info...OK
  ERROR! Failed to install app '4020' (Missing configuration)

and exit 8, before a byte of depot. Reproduced on the same machine, in a
fresh container, with 31 GB free — and the very same line, in another fresh
container ten minutes later, downloaded all 6.87 GB. Steam had not handed
out the app's configuration, and nothing on the node decides that.

One attempt turned a passing Steam mood into an installation somebody has to
notice and start again, on a download measured in gigabytes. So the depot is
now fetched up to three times. Three and not thirty: a real failure — a wrong
app id, a full volume — fails the same way every time, and is better reported
in a minute than in an hour. A retry costs little either, since Steam keeps
what it has already staged under steamapps/downloading.

And when it does give up, it says which of three things happened, because
none of their fixes is guessable from what SteamCMD prints:

  Missing configuration  Steam refused; nothing local, reinstall later.
  state is 0x202         Out of room. Measured by giving the volume 1.9 GB
                         for a 6.87 GB depot: the download stages into
                         steamapps/downloading, so the install wants about
                         twice the finished size free, not once.
  No subscription        The app id is not anonymously installable.

Anything else prints SteamCMD's own last words, which is what it did before.

`tee` rather than a redirection: the operator goes on watching the download
in their console — an install that goes silent for six gigabytes looks stuck
— while the last attempt is kept for the diagnosis.

Shared by every Source template, so Garry's Mod and its neighbour both get
it. Four tests, and the loop was exercised against a fake steamcmd failing
zero, one, two and three times.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ReX2JSG6VKYShanE1F69KP
@aaldersondev

Copy link
Copy Markdown
Contributor Author

Closing this one: the investigation went further and the premise here is wrong.

This PR claimed the refusal was a passing Steam mood, on the evidence that the same command failed in one container and succeeded in another ten minutes later. That comparison had an uncontrolled variable. The two containers differed by more than time: the failing one had a pty.

Measured on the same machine, interleaved so that time cannot explain it — eight trials, and the correlation is perfect:

Container Result
-t Missing configuration, every time (7 runs)
no -t downloads, every time (3 runs)

TERM=xterm without a pty downloads; a pty with TERM= empty fails. So it is the terminal, not the environment.

The daemon creates the install container with Tty: true, so every SteamCMD install on Hopper hits this — including the 104 of 274 published Pterodactyl eggs that install from Steam. That is the thing to fix, and a retry loop around it would only have retried a deterministic failure three times before reporting the same message.

The retry and the failure table are still worth having and come back in the replacement, with wording that says what this actually is.

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