Skip to content

Commit 9632dbb

Browse files
Fix Docker cache tag length exceeding 128 character limit
Docker image tags have a maximum length of 128 characters. When building with long base image names (e.g., SWE-Bench images like scikit-learn), the generated cache tags can exceed this limit and cause build failures with: 'ERROR: failed to configure registry cache exporter: invalid reference format' This issue occurs when the base_image_slug (created from the base image name with / and : replaced) combined with the cache prefix and branch name exceeds 128 characters. Solution: Hash the base_image_slug when it would cause the final cache tag to exceed 128 characters. Uses SHA256 hash (first 12 chars) to create a shorter unique identifier while maintaining cache efficiency across builds. The fix: - Imports hashlib for SHA256 hashing - Calculates the maximum available space for base_slug given the prefix and branch suffix - If the base_slug would cause overflow, replaces it with a 12-char hash - Preserves the original slug for shorter image names (no impact on common use cases) This maintains cache effectiveness while supporting arbitrarily long base image names. Co-authored-by: openhands <[email protected]>
1 parent 54c5858 commit 9632dbb

File tree

1 file changed

+32
-1
lines changed
  • openhands-agent-server/openhands/agent_server/docker

1 file changed

+32
-1
lines changed

openhands-agent-server/openhands/agent_server/docker/build.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"""
1515

1616
import argparse
17+
import hashlib
1718
import os
1819
import re
1920
import shutil
@@ -284,7 +285,37 @@ def versioned_tag(self) -> str:
284285

285286
@property
286287
def cache_tags(self) -> tuple[str, str]:
287-
base = f"buildcache-{self.target}-{self.base_image_slug}"
288+
# Docker image tags have a 128-character limit.
289+
# If the base slug is too long, hash it to create a shorter unique identifier.
290+
MAX_TAG_LENGTH = 128
291+
base_slug = self.base_image_slug
292+
293+
# Reserve space for prefix, branch, and separators
294+
prefix = f"buildcache-{self.target}-"
295+
branch_suffix = (
296+
f"-{_sanitize_branch(GIT_REF)}"
297+
if GIT_REF not in ("main", "refs/heads/main", "unknown")
298+
else ""
299+
)
300+
main_suffix = "-main" if GIT_REF in ("main", "refs/heads/main") else ""
301+
302+
# Calculate available space for base_slug
303+
reserved = len(prefix) + max(len(branch_suffix), len(main_suffix))
304+
available = MAX_TAG_LENGTH - reserved
305+
306+
# If base_slug is too long, use a hash
307+
if len(base_slug) > available:
308+
# Use first 8 chars of SHA256 hash for uniqueness while keeping it short
309+
hash_digest = hashlib.sha256(base_slug.encode()).hexdigest()[:12]
310+
base_slug_short = hash_digest
311+
logger.debug(
312+
f"[build] Base image slug too long ({len(base_slug)} chars), "
313+
f"using hash: {base_slug_short}"
314+
)
315+
else:
316+
base_slug_short = base_slug
317+
318+
base = f"{prefix}{base_slug_short}"
288319
if GIT_REF in ("main", "refs/heads/main"):
289320
return f"{base}-main", base
290321
elif GIT_REF != "unknown":

0 commit comments

Comments
 (0)