Argos CI Screenshot Upload Failed: Common Causes and Fixes
Missing screenshots or failed Argos uploads usually come down to capture, file selection, authentication, project linkage, or size. Diagnose them in order.
If an Argos CI screenshot upload failed, first check that the capture and upload steps both ran, then confirm the generated files match the uploader’s root and glob. After that, check which authentication path the job is using, whether the repository is connected to the intended Argos project, and whether any uploaded snapshot exceeds 50 MB. A screenshot created by a test is not necessarily selected for upload.
The exact cause depends on your workflow, package version, logs, and error message. Work through the checks below in order, keeping file-generation failures separate from upload or project-verification failures.
1. Confirm the workflow captures screenshots and runs the uploader
In the Argos Playwright quickstart, the reporter uploads automatically when it detects a CI environment. Its example also gates uploads with uploadToArgos: !!process.env.CI. Check that the reporter is configured and that the upload step is not skipped by a condition or missing CI context. The argosScreenshot helper captures a named visual snapshot; simply taking a Playwright screenshot does not establish that the Argos upload path will select it. See the Argos Playwright quickstart.
Start with the workflow log: did the test command run, did it reach the screenshot code, and did the reporter or explicit upload command run afterward? If the uploader never starts, investigate workflow conditions, job dependencies, and environment variables before changing credentials.
2. Match the generated files to the configured path and glob
The quickstart helper writes to ./screenshots by default. For direct SDK uploads, the root identifies the directory and files selects matching paths. Compare those values with the actual CI working directory, output directory, and file extensions. The SDK example uses root: "./screenshots" and files: ["**/*.png"]. See the Argos Node.js SDK reference.
import { upload } from "@argos-ci/core";
const { build } = await upload({
root: "./screenshots",
files: ["**/*.png"],
token: process.env.ARGOS_TOKEN,
});
console.log(`Build created: ${build.url}`);
Before changing the glob, list the files in the CI job. Check for an unexpected working directory, nested output folders, a different extension such as .webp, or screenshots written to a temporary directory. If no files exist, fix capture or test setup. If files exist but do not match the selection, correct the root or glob.
The Argos quickstart recommends adding its generated screenshots directory to .gitignore so test output is not committed. That does not prevent CI from uploading the files during the run.
3. Check the Argos CLI upload command
If you upload a directory with the CLI, confirm the path exists at the point the command runs and that the token is available in that same step. The package README documents this command shape:
ARGOS_TOKEN="YOUR_ARGOS_TOKEN" npx @argos-ci/cli upload ./screenshots
CLI flags and behavior can depend on the installed package version. Check the official Argos CLI documentation for the version in your lockfile before changing flags. Avoid printing the token itself in logs.
4. Identify the authentication method the job actually uses
For GitHub Actions, Argos selects ARGOS_TOKEN first. If it is unset, the SDK can use OIDC when the job has id-token: write and OIDC is enabled in the Argos project. Otherwise, it can use tokenless authentication. A secret inherited from a repository, environment, or reusable workflow can therefore make the job use a project token when you expected OIDC. The Argos GitHub Actions authentication guide documents the methods and selection order.
| Method | What to check | When it fits |
|---|---|---|
| Project token | ARGOS_TOKEN is available to the upload step and belongs to the intended project. |
Any supported CI provider. The token is a long-lived secret that needs secure storage and rotation. |
| OIDC | GitHub OIDC is enabled in Argos Project Settings → Authentication, and the upload job has id-token: write. |
GitHub Actions jobs where you want short-lived identity instead of a stored Argos token. |
| Tokenless | ARGOS_TOKEN is unset, and the upload runs in a GitHub Actions context Argos can verify. |
GitHub Actions, including fork pull requests where secrets and OIDC may not be available. |
For OIDC, permissions belong on the job that actually runs the Argos reporter or uploader. A permission on another job does not grant access to this one. The guide’s example also includes contents: read and pull-requests: read for checkout and pull-request association.
name: Visual tests
on: [pull_request]
jobs:
visual-tests:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
id-token: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npx playwright test
This example shows the job-level OIDC permission placement. It assumes the Playwright reporter is already installed and configured as described in the Argos quickstart, and OIDC has been enabled in the Argos project. If using a project token instead, provide ARGOS_TOKEN as a GitHub Actions secret to the step that uploads, and do not expose it in command output.
For CI providers other than GitHub Actions, the Argos guide says tokenless authentication is unavailable; use a project token. The Playwright reporter also supports a token option in its configuration.
5. Check repository matching and project selection
Tokenless verification depends on Argos finding a matching GitHub workflow run in progress. Check that the workflow repository is connected to the Argos project and that the upload happens while GitHub still reports the matching run as in progress. A repository mismatch, an upload that happens too late, or multiple Argos projects linked to one repository can prevent verification or project resolution.
If several projects share the repository, explicitly select the intended project slug, such as account/project-name. The authentication guide describes setting ARGOS_PROJECT, or passing the project through the applicable CLI or SDK option. Follow the syntax for your installed version.
For an upload accepted without pull-request details, distinguish build upload from PR association. Argos documents that tokenless authentication alone does not link a build to a pull request; providing GITHUB_TOKEN lets the SDK resolve the PR.
6. Match the error message to the likely fix
| Symptom or message | Likely cause | Fix |
|---|---|---|
| No screenshots appear in the Argos build | The reporter or uploader did not run, or the configured root/glob selected no files. | Check the workflow log, list generated files, then align the path and file pattern. |
| “Unable to get OIDC token” or an OIDC 403 | The uploading job lacks permission to request an identity token, or OIDC is not enabled for the project. | Give that job id-token: write and enable GitHub OIDC in Argos Project Settings → Authentication. |
| Argos appears to use a token instead of OIDC | ARGOS_TOKEN is set in the job, environment, repository, or reusable workflow. |
Check whether the variable is set without logging its value. Remove it if the intended path is OIDC. |
| “Repository does not match the Argos project” | The workflow is running in a repository other than the one connected to the project. | Verify the project’s repository connection or use the intended project. |
| “No matching workflow run found” | Argos cannot verify the current run, often because the repository link or run context does not match, or upload started after the run was no longer in progress. | Check repository, commit, branch, and timing; upload during the matching workflow run. |
| “Multiple projects are linked to this repository” | Project resolution is ambiguous. | Set the intended project slug explicitly. |
| Build exists but PR metadata is absent | Tokenless upload succeeded, but tokenless alone did not resolve the pull request. | Provide GITHUB_TOKEN for PR resolution as described in the Argos guide. |
| Upload reports an oversized item | A snapshot, screenshot, or trace exceeds the documented per-snapshot limit. | Inspect individual attachments and reduce or exclude oversized output. |
7. Check the per-snapshot size limit
The Argos Playwright SDK reference documents a limit of 50 MB for each uploaded snapshot, including screenshots and traces. If the error mentions payload or item size, inspect individual files rather than assuming the total screenshot folder is the issue. The limit is per snapshot; traces are included. See the Playwright reference.
8. Separate upload failures from visual test failures
A visual mismatch or flaky screenshot can look like a broken upload even when Argos received the build. The Playwright reporter can upload failure screenshots and traces for test debugging; those diagnostics require the reporter and corresponding Playwright settings, such as trace: "on-first-retry" and screenshot: "only-on-failure". They do not prove that normal visual snapshots were selected for upload.
For inconsistent rendering between local and CI runs, Argos’s Playwright example recommends Chromium flags --disable-lcd-text and --font-render-hinting=none. These address rendering consistency, not credentials, file selection, or rejected uploads. Keep the diagnosis aligned with the actual symptom.
9. Preserve CI output to narrow down the fault
When it is unclear whether CI generated the screenshots, save the screenshot directory and relevant logs as a GitHub Actions artifact. GitHub describes artifacts as files produced by a workflow that can be retained after a job and shared with another job; screenshots and test failures are common examples. Downloading the artifact lets you inspect what existed before Argos upload. It does not authenticate with Argos or complete an Argos upload. See GitHub’s workflow artifacts documentation.
- name: Preserve screenshots for diagnosis
if: always()
uses: actions/upload-artifact@v4
with:
name: playwright-screenshots
path: screenshots/
if-no-files-found: warn
Use this as a temporary diagnostic or as a retained test artifact if useful. If the artifact is empty, the problem precedes Argos upload. If it contains the expected files, focus on Argos selection, authentication, project matching, or size.
10. A short diagnostic checklist
- Confirm the test and screenshot capture code ran in this workflow run.
- Confirm the Argos reporter or explicit CLI/SDK uploader ran after capture.
- List the output directory and compare it with the configured root and glob.
- Identify the active authentication method; check token presence without printing secret contents.
- For OIDC, check project enablement and permission on the upload job.
- For tokenless uploads, verify the repository, commit, branch, and in-progress workflow context.
- If multiple projects share a repository, set the intended project slug.
- Check individual snapshots and traces against the 50 MB limit.
- Preserve screenshots as a GitHub artifact if you need to prove what CI generated.
Or skip the browser setup
For a separate screenshot capture workflow, ScreenshotNeo is a website screenshot API and MCP server. One GET request returns an image or PDF; see the ScreenshotNeo API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));
ScreenshotNeo removes cookie and consent banners, newsletter popups, and chat widgets before capture. Bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The Free plan includes 1,000 screenshots a month with no card, and paid plans start at $5 for 3,000. Sign up for 1,000 free screenshots a month, with no card required.
Performance, reliability, and cost notes
For Argos CI diagnosis, avoid adding repeated upload attempts before confirming file selection and credentials; retries cannot correct an empty glob, wrong project, or missing permission. Preserve the generated files once and inspect the exact uploader output. The cited Argos material documents the 50 MB per-snapshot ceiling, but does not establish a universal upload latency, retry guarantee, or service-wide incident as the cause of an individual failure.
A project token requires secret provisioning and rotation. OIDC avoids a stored Argos token but requires project configuration and job permission. Tokenless removes token setup for supported GitHub Actions cases, including fork PRs, but depends on run verification and can require explicit project selection. Choose the path that fits your CI provider and repository trust model; do not assume one mode is active from workflow intent alone.
FAQ
Why did Argos accept the build but show no screenshots?
The upload may have created a build while the reporter or glob selected no snapshots. Check the actual output files against the reporter configuration or SDK root and file pattern.
Does a GitHub Actions artifact fix Argos authentication?
No. It preserves files for inspection. It can show whether screenshots existed before upload, but Argos still needs a valid uploader and authentication path.
Can I use tokenless authentication on another CI provider?
The Argos authentication guide describes tokenless authentication for GitHub Actions. For other CI providers, it recommends an Argos project token.
Is a Playwright trace the same thing as an Argos visual snapshot?
No. A trace is diagnostic output. The SDK’s 50 MB per-snapshot limit includes traces, but uploading a trace does not itself configure regular visual snapshots.


