Skip to content

Log why a new repository couldn't be created - #436

Open
David Larsen (dc-larsen) wants to merge 3 commits into
mainfrom
dc-larsen/repo-create-error-visible
Open

David Larsen (dc-larsen) wants to merge 3 commits into
mainfrom
dc-larsen/repo-create-error-visible

Conversation

@dc-larsen

@dc-larsen David Larsen (dc-larsen) commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

When a repository isn't in Socket yet and the API token can't create it (for example, the token has repo:list but not repo:create), the CLI exits 2 right after file discovery with nothing logged, so CI users have no way to tell what went wrong. Related to CE-127.

Root Cause

get_repo_info sets the socketdev logger to CRITICAL around the repository lookup and only restored the level after a successful lookup. socketsecurity.core logs through that same logger, so when the lookup raised (a 404 for a repository Socket hasn't seen), the "attempting to create it" warning and the creation error were both dropped before sys.exit(2). When the create succeeded, logging stayed muted for the rest of the run.

Fix

  • Restore the logger level in a finally around the lookup.
  • Include the repository, the HTTP status and, on a 403, a repo:create hint in the creation error. The SDK keeps only the API's Insufficient permissions message and drops the required scope from the response.
  • The exit code on this path is unchanged (2).
  • Two tests in tests/core/test_sdk_methods.py. Both fail on main: no records reach the log, and the logger is still at CRITICAL after a successful create.

Testing

  • uv run pytest tests/unit tests/core: 729 passed. ruff check clean, uv lock --locked in sync, hatch build + twine check pass.
  • Live against the API with a token that has repo:list but not repo:create, on a repository Socket hadn't seen:
    • Before (2.5.0 and 2.11.6): exit 2, the log ends at File count (1) is within file descriptor limit.
    • After, at the default log level: exit 2 with
      Failed to get repository <repo>, attempting to create it
      API failure while creating repository <repo> (HTTP 403): Insufficient permissions
      A 403 here usually means the API token is missing the repo:create scope.
      
  • Same token after adding repo:create: the CLI creates the repository and completes the scan (exit 0), with logging continuing after the create. A rerun on the now-existing repository takes the normal path with no create attempt.

Follow-up changes (pushed by lelia)

Creation error. The SDK appends the request path and the response headers to APIAccessDenied's message, so the error now logs only its first line. APIInsufficientPermissions has no message, so the line falls back to the exception type. The repo:create hint no longer fires on quota or organization-not-allowed 403s.

Version 2.11.10, not 2.11.9. v2.11.8 and v2.11.9 are published, immutable GitHub releases with nothing on PyPI or Docker Hub. Each was tagged one ahead of the package version at its commit, so the release workflow's tag/version check correctly refused to publish. PyPI's latest is still 2.11.6, so this release also ships the Coana 15.13.3 and 15.14.0 bumps (#431, #434). The 2.11.7 and 2.11.8 CHANGELOG entries are folded into 2.11.10.

Release process guards:

  • version-check.yml fails when v<version> is already a tag. It used to compare against PyPI and main only, which is why 2.11.9 passed here.
  • release.yml opens an issue that mentions @SocketDev/customer-engineering when a release run fails. Until now only the person who published the release was notified.

Public Changelog

The Socket Python CLI now explains why it couldn't create a repository that isn't in Socket yet, including the HTTP status and a hint about the repo:create scope, instead of exiting with no output. This release also bumps the pinned Coana CLI to 15.14.0.


Note

Low Risk
Localized logging and error-message changes in get_repo_info; no change to exit codes or API behavior beyond surfacing failures that were already occurring.

Overview
Fixes a silent exit 2 when the CLI tries to auto-create a repository that is not in Socket yet but the API token cannot create it (for example missing repo:create).

In Core.get_repo_info, the socketdev logger is temporarily set to CRITICAL during the repo lookup. The level is now restored in a finally block so a failed lookup no longer leaves logging muted for the rest of the run. That restores the “attempting to create it” warning and creation error lines that were previously dropped because socketsecurity.core also logs through socketdev.

When repository creation fails, errors now include the repo slug, HTTP status when available, and on 403 a hint that the token may need repo:create. Exit code 2 on that path is unchanged. Release 2.11.9 with matching tests.

Reviewed by Cursor Bugbot for commit aa2299b. Configure here.

get_repo_info mutes the socketdev logger around the repository lookup
and only restored the level after a successful lookup. This module logs
through the same logger, so when the lookup raised for a repository
that isn't in Socket yet, the "attempting to create it" warning and the
creation error were dropped, and the CLI exited 2 right after file
discovery with nothing logged. A successful create also left logging
muted for the rest of the run.

Restore the level in a finally block, and include the repository, the
HTTP status and, on a 403, a repo:create hint in the creation error.
The SDK keeps only the API's "Insufficient permissions" message and
drops the required scope.

Bump to 2.11.9.
The SDK appends the request path and the response headers to
APIAccessDenied's message, so logging the exception as-is printed a
multi-line header dump at the default log level. APIInsufficientPermissions
carries no message at all, which left the line ending in ": ". Log the
first line, falling back to the exception type.

Quota and organization-not-allowed errors are also 403s, so the
repo:create hint no longer fires for those.

Bump to 2.11.10: v2.11.9 is already taken by an existing tag and GitHub
release (#434), even though that release never reached PyPI.
@lelia
lelia deployed to socket-firewall November 2, 2026 21:27 — with GitHub Actions Active
Releases are immutable, so a published release's tag can't be moved or
reused even when its release run fails. v2.11.8 and v2.11.9 were tagged
one ahead of the package version at their commits, failed the release
workflow's tag/version check, and left nothing on PyPI or Docker Hub.
Only the person who published them was notified.

- Version Check now fails when v<version> is already a tag, since PyPI
  alone can't tell that a version has been burned.
- The release workflow opens an issue for the team when it fails, with
  the run, the tag, the package version and what to do next.
- Fold the never-published 2.11.7 and 2.11.8 changelog entries into
  2.11.10, which is the first release to ship them.
@lelia
lelia deployed to socket-firewall November 2, 2026 21:41 — with GitHub Actions Active
@lelia lelia self-assigned this Nov 2, 2026

This branch was successfully deployed

1 active deployment
socket-firewall — 12e4e1cd Deployed Nov 2, 2026 by lelia via python-sfw-smoke-enterprise #545
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