Describe the bug
This is a real bug reported and seen by me (not a AI generated slop) in our Nix CI where we use codecov upload-coverage ....
This bug made me pin to 10.4.0 for a long time (with Nix) because the 11.2.6 does not work:
- The 10.4.0 binary does handle
--auto-load-params-from githubactions fine.
- The binary 11.2.6 does not, all loaded values are
null (same environment)
I used Claude Opus 4.8 debugging showed me that the problem seems to be in codecov click dependency.
Could somebody confirm that this is the root cause?
CodecovOption CI-adapter fallback broken with click ≥ 8.3 (--slug not auto-loaded → "The provided slug is invalid")
Root cause
click 8.3 introduced an UNSET sentinel: click.Parameter.get_default() now returns UNSET (not None) when an option has no explicit default.
CodecovOption.get_default in codecov_cli/fallbacks.py only guards against None:
def get_default(self, ctx, call=True):
res = super().get_default(ctx, call=call)
if res is not None: # UNSET is not None -> returns here
return res
if self.fallback_field is not None:
if ctx.obj.get("ci_adapter") is not None:
res = ctx.obj.get("ci_adapter").get_fallback_value(self.fallback_field)
...
Summary
The CI-adapter fallback for CodecovOption options no longer fires when running with click >= 8.3. As a result, upload-coverage (and the individual commands) ignore auto-loadable parameters such as the repo slug, even though --auto-load-params-from is passed and the CI env vars are present. With --slug unset, the upload fails with:
ValueError: The provided slug is invalid
File ".../codecov_cli/helpers/encoder.py", line 10, in encode_slug
raise ValueError("The provided slug is invalid")
Reproduction
In a GitHub Actions-like environment (GITHUB_ACTIONS=true, GITHUB_REPOSITORY=owner/repo set) run without --slug:
codecov --auto-load-params-from githubactions upload-coverage \
--network-root-folder . --flag myflag --disable-search \
--commit-sha <sha> --token <token> -f coverage.txt
The --dry-run debug log shows "slug": null even though GITHUB_REPOSITORY is set and readable.
Expected vs actual
- Expected: slug is auto-loaded from the GitHub Actions adapter (
GITHUB_REPOSITORY), as it was with click 8.2.x.
- Actual: slug stays
None; encode_slug(None) raises "The provided slug is invalid".
Because super().get_default() now returns UNSET (truthy, not None), the method returns early and the CI-adapter / versioning-system fallback below becomes dead code.
Confirmed by introspection under click 8.3.1:
adapter.get_fallback_value(FallbackFieldEnum.slug) → 'owner/repo' (adapter works)
slug_option.get_default(ctx) → Sentinel.UNSET (fallback skipped)
Any CodecovOption field with no explicit default that relies on the fallback is affected (slug, git-service, etc.). --commit-sha masks the issue when passed explicitly.
Suggested fix
Treat click's UNSET sentinel as "no value" in the override, e.g.:
try:
from click.core import UNSET # click >= 8.3
except ImportError:
UNSET = None
def get_default(self, ctx, call=True):
res = super().get_default(ctx, call=call)
if res is not None and res is not UNSET:
return res
...
return None # normalize UNSET -> None on the fallback miss path too
Describe the bug
This is a real bug reported and seen by me (not a AI generated slop) in our Nix CI where we use
codecov upload-coverage ....This bug made me pin to
10.4.0for a long time (with Nix) because the 11.2.6 does not work:--auto-load-params-from githubactionsfine.null(same environment)I used Claude Opus 4.8 debugging showed me that the problem seems to be in codecov
clickdependency.Could somebody confirm that this is the root cause?
CodecovOptionCI-adapter fallback broken with click ≥ 8.3 (--slugnot auto-loaded → "The provided slug is invalid")Root cause
click8.3 introduced anUNSETsentinel:click.Parameter.get_default()now returnsUNSET(notNone) when an option has no explicit default.CodecovOption.get_defaultincodecov_cli/fallbacks.pyonly guards againstNone:Summary
The CI-adapter fallback for
CodecovOptionoptions no longer fires when running withclick >= 8.3. As a result,upload-coverage(and the individual commands) ignore auto-loadable parameters such as the repo slug, even though--auto-load-params-fromis passed and the CI env vars are present. With--slugunset, the upload fails with:Reproduction
In a GitHub Actions-like environment (
GITHUB_ACTIONS=true,GITHUB_REPOSITORY=owner/reposet) run without--slug:The
--dry-rundebug log shows"slug": nulleven thoughGITHUB_REPOSITORYis set and readable.Expected vs actual
GITHUB_REPOSITORY), as it was with click 8.2.x.None;encode_slug(None)raises "The provided slug is invalid".Because
super().get_default()now returnsUNSET(truthy, notNone), the method returns early and the CI-adapter / versioning-system fallback below becomes dead code.Confirmed by introspection under click 8.3.1:
adapter.get_fallback_value(FallbackFieldEnum.slug)→'owner/repo'(adapter works)slug_option.get_default(ctx)→Sentinel.UNSET(fallback skipped)Any
CodecovOptionfield with no explicit default that relies on the fallback is affected (slug, git-service, etc.).--commit-shamasks the issue when passed explicitly.Suggested fix
Treat click's
UNSETsentinel as "no value" in the override, e.g.: