mirror of
https://github.com/Sea-Haven-Industries/open-swe.git
synced 2026-10-07 16:19:09 +00:00
fix: casefold repo-binding keys to avoid spurious cross-repo mismatch
GitHub owner/name are case-insensitive. Casefold the owner/name key on both the write (binding) and read (compare) sides — repo_cache_key and the metadata bound_repo read — so Org/Repo and org/repo resolve to one repo and a legitimate same-repo run cannot raise a spurious SandboxRepoMismatchError (Gap 2).
This commit is contained in:
parent
d880cdabb3
commit
ebeb2663fd
2 changed files with 12 additions and 4 deletions
|
|
@ -28,15 +28,20 @@ class GitHubAuthError(Exception):
|
|||
|
||||
|
||||
def repo_cache_key(repo: Any) -> str | None:
|
||||
"""Normalize a repo dict/string to ``owner/name`` (None when unknown)."""
|
||||
"""Normalize a repo dict/string to a casefolded ``owner/name`` (None if unknown).
|
||||
|
||||
GitHub owner/name are case-insensitive, so the key is casefolded on both the
|
||||
write (binding) and read (compare) sides to keep ``Org/Repo`` and ``org/repo``
|
||||
a single repo and avoid spurious cross-repo mismatches.
|
||||
"""
|
||||
if isinstance(repo, str):
|
||||
cleaned = repo.strip()
|
||||
return cleaned or None
|
||||
return cleaned.casefold() or None
|
||||
if isinstance(repo, Mapping):
|
||||
owner = repo.get("owner")
|
||||
name = repo.get("name")
|
||||
if isinstance(owner, str) and isinstance(name, str) and owner and name:
|
||||
return f"{owner}/{name}"
|
||||
return f"{owner}/{name}".casefold()
|
||||
return None
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ from deepagents.backends.protocol import (
|
|||
)
|
||||
from langgraph.config import get_config
|
||||
|
||||
from .github_token import repo_cache_key
|
||||
from .sandbox import create_sandbox
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
|
@ -167,7 +168,9 @@ async def get_bound_repo_from_metadata(thread_id: str) -> str | None:
|
|||
if not isinstance(metadata, dict):
|
||||
return None
|
||||
bound_repo = metadata.get("bound_repo")
|
||||
return bound_repo if isinstance(bound_repo, str) and bound_repo else None
|
||||
# Casefold on read so legacy metadata written before normalization (e.g.
|
||||
# ``Org/Repo``) still compares equal to the casefolded current repo key.
|
||||
return repo_cache_key(bound_repo) if isinstance(bound_repo, str) and bound_repo else None
|
||||
|
||||
|
||||
def clear_sandbox_backend(thread_id: str) -> None:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue