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

  1. Fix the token-file env var to point to an existing readable file, or set the token directly via the token env var.
  2. Verify file permissions and that the volume mount is present in the deployment.
  3. 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

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_PATH

View on GitHub (pinned to 5e758547a8)