Skip to content

Visibility check blocks push on transient GitHub API failures #959

@james-in-a-box

Description

@james-in-a-box

Problem

Push operations can be blocked by the fail-closed visibility policy when
the GitHub API is transiently unavailable (timeout, rate limit, connection
error). The error message is:

Cannot determine visibility for repository 'owner/repo'.
Private Repo Mode requires explicit verification.

This affects all modes (public and private), since the visibility check
runs unconditionally before every push, PR create, and other git operations.

Root Cause

Two factors combine to make this fragile:

  1. Write operations bypass the visibility cacheDEFAULT_VISIBILITY_CACHE_TTL_WRITE = 0
    in gateway/repo_visibility.py, so every push makes a live GitHub API call.

  2. No retry on transient failures_fetch_visibility_with_token() returns None
    immediately on any error (timeout, 403, 5xx, connection error), and the policy
    engine treats visibility=None as "deny access" (fail-closed).

A single transient GitHub API hiccup (rate limit window, brief timeout, DNS
blip) is enough to block a legitimate push.

Observed Behavior

First push attempt:

ERROR: Cannot determine visibility for repository 'jwbron/egg'.
PUSH BLOCKED BY POLICY

Immediate retry (same command): succeeds.

Fix

PR #957 adds retry with exponential backoff (3 attempts, 1s/2s) to
_fetch_visibility_with_token() for retryable errors:

  • requests.Timeout and requests.ConnectionError
  • HTTP 403 (rate limit) and 5xx (server errors)

Non-retryable responses (404, 200) return immediately as before.

Future Considerations

  • The write TTL of 0 means every push requires a live API call. A short
    write TTL (e.g., 5-10s) would prevent rapid successive pushes from all
    hitting the API, while still being fresh enough for security purposes.
  • The error message "Private Repo Mode requires explicit verification" is
    misleading when running in public mode — the actual issue is an API failure,
    not a mode mismatch.

— Authored by egg

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions