iflytek/astron-agent · error · RuntimeError
Artifact upload credential is missing or invalid
Error message
Artifact upload credential is missing or invalid
What it means
_load_artifact_upload_token resolves the artifact-upload credential from an env var or a token file. It raises RuntimeError(ARTIFACT_UPLOAD_CREDENTIAL_ERROR) when the file named by the token-file env var cannot be read (OSError/UnicodeError), because then no usable credential exists for uploading artifacts out of the E2B sandbox.
Solutions
- Fix the token-file env var to point to an existing readable file, or set the token directly via the token env var.
- Verify file permissions and that the volume mount is present in the deployment.
- Regenerate/replace the token file with valid UTF-8 content.
Example fix
// before ARTIFACT_UPLOAD_TOKEN_FILE=/secrets/missing-token // after ARTIFACT_UPLOAD_TOKEN_FILE=/etc/astron/artifact-upload-token # file exists and is readable
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path p = Path(os.environ["ARTIFACT_UPLOAD_TOKEN_FILE"]) assert p.is_file() and p.stat().st_size > 0, "token file missing/empty" text = p.read_text(encoding="utf-8") # raises UnicodeError early if not UTF-8
Try / catch
try:
ex.upload(...)
except RuntimeError as e:
if "credential" in str(e): alert("artifact upload token unreadable"); skip artifact step Prevention
- Mount secrets read-only at a stable path and verify at startup
- Check file readability in a readiness probe
- Keep token files single-line UTF-8
When it happens
Trigger: ARTIFACT_UPLOAD_TOKEN_FILE_ENV points to a nonexistent, unreadable, or invalid-UTF-8 file; Path.read_text raises OSError or UnicodeError during upload().
Common situations: Token file path misconfigured in the container, file not mounted, permissions changed, or the file contains binary/invalid encoding.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12).
Data as JSON: /api/errors/06dedb94acb2cf7c.
Report an issue: GitHub.
Appendix: source
Thrown at core/workflow/engine/nodes/code/executor/e2b/e2b_executor.py:156
pass
print('{"error":"snapshot_failed"}')
finally:
if source_fd is not None:
os.close(source_fd)
if destination_fd is not None:
os.close(destination_fd)
""".strip()
def _load_artifact_upload_token() -> str:
token = (os.getenv(ARTIFACT_UPLOAD_TOKEN_ENV) or "").strip()
if not token:
token_file = (os.getenv(ARTIFACT_UPLOAD_TOKEN_FILE_ENV) or "").strip()
if token_file:
try:
token = Path(token_file).read_text(encoding="utf-8").strip()
except (OSError, UnicodeError) as exc:
raise RuntimeError(ARTIFACT_UPLOAD_CREDENTIAL_ERROR) from exc
if len(token) < MIN_ARTIFACT_UPLOAD_TOKEN_LENGTH or "\r" in token or "\n" in token:
raise RuntimeError(ARTIFACT_UPLOAD_CREDENTIAL_ERROR)
return token
def _load_artifact_upload_url() -> str:
artifact_upload_url = (os.getenv(ARTIFACT_UPLOAD_URL_ENV) or "").strip()
try:
parsed = urlsplit(artifact_upload_url)
if (
not artifact_upload_url
or len(artifact_upload_url) > 2048
or any(char in artifact_upload_url for char in ("\r", "\n", "\t"))
or parsed.scheme not in {"http", "https"}
or not parsed.hostname
or parsed.username is not None
or parsed.password is not None
or parsed.path != ARTIFACT_UPLOAD_PATHView on GitHub (pinned to 5e758547a8)