Filing issues
Upliftr is AI debugging agents that reproduce a bug in a real browser and root-cause it, read-only by design. When an agent confirms a failure, it files a deduped, root-caused issue to the destinations you configure. Out of the box Upliftr has its own tracker, "File to Upliftr", and the agents can also open issues in GitHub, GitLab, and Jira.
How a failure becomes a root-caused issue (and gets a backend diagnosis) is covered in Self-heal & root-cause.
Destinations
By default a verified failure lands on the built-in Upliftr board (the in-app Issues page), your source of truth for analytics, dedup, and triage. FILE_ISSUES chooses any external tracker(s) to also mirror to. Set it in Settings (the "Also mirror to" picker), pass file_issues when starting a run, or --file-issues on the CLI; comma-separate for several, e.g. github,jira.
To opt out entirely for a run (don't even record on the board), pass none (the run dropdown's "Don't file issues"), it's respected, so nothing is written.
| Destination | What it does | Config |
|---|---|---|
upliftr | Built-in tracker, issues live in the platform (the Issues page). | none |
github | Opens / comments a GitHub issue. | GITHUB_TOKEN, GITHUB_REPO |
gitlab | Opens / comments a GitLab issue. | GITLAB_TOKEN, GITLAB_PROJECT, GITLAB_URL? |
jira | Creates / comments a Jira issue (ADF). | JIRA_BASE, JIRA_EMAIL, JIRA_TOKEN, JIRA_PROJECT |
GITLAB_URL is optional, set it for self-managed GitLab (GITLAB_PROJECT is the numeric id or url-encoded group%2Fproject path). Jira issues are formatted with Atlassian Document Format (ADF) and created as Bug type in JIRA_PROJECT. If a provider's credentials aren't set, that provider is skipped (the run still succeeds), the others still file.
Use a dedicated Upliftr account
Don't use a personal token. Create a service account in the tracker, a bot user that exists only to file Upliftr issues, and configure Upliftr with its token.
These credentials are set once, centrally, by an admin, on the dashboard's Settings page (admin-only) or as deployment environment variables. Everyone else just chats with the agents and inherits them; members never enter their own token. A dedicated account is the right way to do this because:
- Issues are authored as "Upliftr", a recognizable bot, not whichever engineer happened to trigger the run.
- Access is scoped to exactly one repo/project, and survives people joining or leaving, filing doesn't break when an engineer rotates a personal token or offboards.
- The audit trail and rate limit belong to the bot, not to a person.
Create the account once, give it write access to the single target repo/project, generate a token as that account, and store it in Upliftr:
| Tracker | Create | Token | Configure |
|---|---|---|---|
| GitHub | A machine user (e.g. upliftr-bot) with write access to the repo. | A fine-grained PAT scoped to that one repo with Issues: Read and write (classic repo scope also works). | GITHUB_TOKEN, GITHUB_REPO=owner/repo |
| GitLab | A service account or bot user with Reporter+ on the project (a Project Access Token works too). | A token with api scope. | GITLAB_TOKEN, GITLAB_PROJECT, GITLAB_URL? |
| Jira | A dedicated Atlassian account (e.g. upliftr@your-co.com) with Create/Edit issue permission in the project. | An API token created as that account. | JIRA_BASE, JIRA_EMAIL (the bot's email), JIRA_TOKEN, JIRA_PROJECT |
The same principle applies to the Anthropic key and the server-log backend: set one org-wide credential as the admin, engineers run against it, they don't bring their own.
Settings & secrets
Integration settings are read and written through the /settings endpoint (and the dashboard's Settings page, which is admin-only). Secrets are masked on read, tokens you've stored are never echoed back in plaintext, and they're encrypted at rest. For CI/headless runs, set the same names as environment variables (see Settings & env).
Per-run override
Override destinations for a single run by passing file_issues when you start it:
curl -X POST http://127.0.0.1:8400/api/v1/runs \
-H 'Content-Type: application/json' \
-d '{"suite": "signup-login.upliftr.yaml", "file_issues": "upliftr"}'Or on the CLI / Action:
upliftr run "suites/*.upliftr.yaml" --file-issues github,jiraThe built-in tracker
The native "File to Upliftr" tracker means you can adopt Upliftr without wiring up an external system first. Issues live on the Issues board in the dashboard and are fully manageable through the API:
| Action | Endpoint |
|---|---|
| List issues (optionally by status) | GET /api/v1/issues?status= |
| Issue detail | GET /api/v1/issues/{id} |
Set status (open / closed / acknowledged) | PATCH /api/v1/issues/{id} |
| Add a comment | POST /api/v1/issues/{id}/comments |
What's in a filed issue
Every issue is built from what the agents reproduced, so it's actionable, not just "check X failed":
- Title,
[Upliftr] <case title>, <reason>. - Severity,
critical/high/medium/low, driven by case status andp0/smoketags. - What failed, the assertion, expected vs. observed, and why.
- Root cause, the failing request, its
trace_id, and (when server logs are connected) the server diagnosis: category, the error line, the suspected cause, a suggested fix, and up to five log-evidence lines. - What worked, the run URL, and the commit.
- Labels,
upliftr,e2e-failure,severity:<sev>, plus the case'stags.
Deduplication
Every failure carries a stable fingerprint:
tw:<suite_id>:<case_id>:<assertion_id>:<failure_class>It's embedded as a hidden marker in the issue body. Before creating, Upliftr searches the tracker for that fingerprint:
- First time a failure is seen → a new issue is opened at each configured destination.
- Subsequent runs of the same failure → Upliftr comments on the existing open issue ("↻ Reproduced again") instead of opening a duplicate.
So a recurring regression accumulates as one issue with a growing occurrence trail, across the built-in tracker, GitHub, GitLab, and Jira alike, not a fresh ticket every nightly run.
Recommended setup
- Just trying it out? Leave the mirror off (
FILE_ISSUES=) and triage on the built-in board. - Team workflow? Set
FILE_ISSUES=github(orgitlab/jira) so failures also land where your engineers already work, the built-in board keeps the full Upliftr view either way. - In CI? The GitLab CI job/component passes
GITLAB_PROJECT/GIT_SHA/CI_RUN_URLfor you; add aGITLAB_TOKENvariable (api scope) and setFILE_ISSUES: gitlabto file. (GitHub/Jira targets work too, set the matching env.)
Next: connect your backend with server logs so each filed issue carries the root cause.