-
Notifications
You must be signed in to change notification settings - Fork 373
[BUG] Localised git stderr breaks auth-failure classification, suppressing the token retry #2533
Copy link
Copy link
Closed
Labels
area/distributionInstallers (curl/PowerShell/Brew/Scoop), self-update, devcontainer, codespaces.Installers (curl/PowerShell/Brew/Scoop), self-update, devcontainer, codespaces.priority/highHuman-set high priority; not scope approval, a release commitment or a required milestone.Human-set high priority; not scope approval, a release commitment or a required milestone.status/acceptedHuman scope approval; verify the issue's approval record and review contact before work.Human scope approval; verify the issue's approval record and review contact before work.status/triagedAutomated advice completed; deduplication only. Not human approval; silence is not approval.Automated advice completed; deduplication only. Not human approval; silence is not approval.theme/portabilityOne manifest, every target. Multi-target deploy, marketplace, packaging, install.One manifest, every target. Multi-target deploy, marketplace, packaging, install.type/bugSomething does not work as documented.Something does not work as documented.
Milestone
Description
Activity
Metadata
Metadata
Assignees
Labels
area/distributionInstallers (curl/PowerShell/Brew/Scoop), self-update, devcontainer, codespaces.Installers (curl/PowerShell/Brew/Scoop), self-update, devcontainer, codespaces.priority/highHuman-set high priority; not scope approval, a release commitment or a required milestone.Human-set high priority; not scope approval, a release commitment or a required milestone.status/acceptedHuman scope approval; verify the issue's approval record and review contact before work.Human scope approval; verify the issue's approval record and review contact before work.status/triagedAutomated advice completed; deduplication only. Not human approval; silence is not approval.Automated advice completed; deduplication only. Not human approval; silence is not approval.theme/portabilityOne manifest, every target. Multi-target deploy, marketplace, packaging, install.One manifest, every target. Multi-target deploy, marketplace, packaging, install.type/bugSomething does not work as documented.Something does not work as documented.
Type
Projects
- StatusShow more project fieldsDone
Describe the bug
AuthResolver.is_public_github_auth_failureclassifies a failed clone by matching English signal strings against git's stderr ("authentication failed","could not read username","repository not found", ...). Git localises those diagnostics through gettext, and APM does not pin a locale for the git subprocesses it spawns itself.On a machine whose locale is not English, git writes its authentication failure in the user's language. The classifier does not recognise it, and the consequence is not cosmetic: the verdict gates the token retry in
try_with_fallback(src/apm_cli/core/auth.py:797-802).Since
uses_public_github_anonymous_firstmakes every github.com access start anonymously, a misclassified failure means the token is never tried. Installing a private-repo dependency fails, and the user is pointed at the wrong cause:while git actually said "authentication failed".
Two things make this hard to spot:
LANGUAGE=C/LC_ALL=Con every command it runs (git/cmd.py). Only APM's ownsubprocesscalls inherit the ambient locale — and that is the path the shared bare cache uses.ja) sees English and is unaffected — until that translation is added.To Reproduce
export LANG=fr_FR.UTF-8(de_DE.UTF-8behaves identically).gh auth login, but not exported in the environment, so it has to come from the retry path.export APM_CACHE_DIR=$(mktemp -d).apm install <org>/<private-repo>/<subdir>— a subdirectory package, which is the case that routes through the shared bare-cache clone.Same command, same token, same repository; only the locale changes:
LC_ALLfr_FR.UTF-8de_DE.UTF-8CLC_ALL=C apm install ...alone makes the install succeed with no code change, which isolates the locale as the cause.The exception captured on the failing path (values redacted):
is_public_github_auth_failurereturnsFalsefor it, sotry_with_fallbackre-raises without trying the token. Instrumenting the same run underLC_ALL=Cyields the untranslatedfatal: Authentication failed, aTrueverdict, and a successful token retry.Expected behavior
Classification of an authentication failure should not depend on the user's locale. A private-repo dependency should install regardless of the language configured on the machine, and a genuine auth failure should be reported as such instead of as a network/proxy problem.
Environment (please complete the following information):
darwin); reproducible on any non-English localemain@3aa0365)share/locale/Additional context
How this surfaced: a shared agent rule hosted in a subdirectory of a private repository. The repository root installed fine, the subdirectory package did not — the subdirectory is what routes through the shared bare cache, whose
subprocesscalls carry the ambient locale. The subdirectory is the trigger, not the cause. The error message sent me looking at proxy and connectivity settings for what was a credential-resolution problem.I have a fix and will open a PR referencing this issue: normalise the message locale in
AuthResolver._build_git_env, the single builder every git env in the auth path routes through. Widening the classifier's vocabulary with translated strings looks like the wrong direction — the catalogues change between git versions and cover a moving set of languages.