> ## Documentation Index
> Fetch the complete documentation index at: https://docs.qlty.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Troubleshooting

This guide helps you troubleshoot common issues with code coverage in Qlty.

## Upload Issues

### Coverage Report Not Being Detected

**Symptoms:**

* "Unsupported format" errors
* "Unable to parse coverage report" messages
* No coverage data appears in Qlty after upload

**Potential Causes:**

* Unsupported coverage format
* Corrupt or incomplete coverage report
* Incorrect file path in upload command

**Solutions:**

1. Verify your coverage format is [supported](/coverage/formats)
2. Check that the coverage report file exists and is complete
3. Try using the `--format` flag to explicitly specify the format:
   ```bash theme={"system"}
   qlty coverage publish --format=lcov path/to/coverage.info
   ```
4. Examine the report file for valid content
5. Generate a fresh coverage report and try again

### Authentication Failures

**Symptoms:**

* "Authentication failed" errors
* "Invalid token" messages
* "Permission denied" errors

**Potential Causes:**

* Incorrect coverage token
* Expired or rotated token
* Missing environment variable
* Using a token with incorrect scope

**Solutions:**

1. Verify your token is correct in your CI settings
2. Check environment variable names (should be `QLTY_COVERAGE_TOKEN`)
3. Regenerate your token in Qlty and update your CI configuration
4. Ensure you're using the token for the correct workspace or project
5. If using OIDC, verify the permissions configuration in your GitHub workflow

### OIDC Token Failures on Forked PRs

**Symptoms:**

* Error: `Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable`
* Coverage upload failures specifically on forked pull requests
* OIDC authentication is working for regular PRs but failing on forks

**Potential Causes:**

* GitHub Actions security restrictions prevent OIDC token generation in workflows triggered by forked pull requests

**Solutions:**
For repositories that accept forked PRs, use Project Coverage Tokens instead of OIDC. See [Coverage Tokens](/coverage/tokens) for setup instructions.

### Path Mapping Issues

**Symptoms:**

* Coverage appears but doesn't match files in your repository
* "File not found" errors when viewing coverage
* Coverage shown for files that don't exist in your repo

**Potential Causes:**

* Coverage report contains absolute paths
* Path structure differs between build environment and repository
* Generated files with different paths

**Solutions:**

1. See [Path Fixing](/coverage/path-fixing) for detailed solutions.

### S3 Upload Failures (403 Errors)

**Symptoms:**

* HTTP 403 Forbidden errors during coverage upload
* "Access denied" messages when uploading to S3
* Coverage upload fails with permission errors

**Potential Causes:**

* Restrictive AWS VPC endpoint policies that block cross-account S3 operations
* VPC endpoint policy doesn't allow `s3:PutObject` action to other AWS accounts

**Solutions:**

We are aware of 1 situation which can cause our coverage uploader to fail to upload with a 403 error: if you have a restrictive AWS VPC endpoint policy which does not allow the S3:PutObject action to another AWS account.

In these cases, you'll need to open up your VPC to allow this action. Here are examples of how to configure this:

<CodeGroup>
  <CodeBlock title="Terraform">
    ```hcl lines theme={"system"}
    {
      effect = "Allow"
      actions = ["s3:PutObject"]
      resources = ["*"]
      principals = {
        type = "AWS"
        identifiers = ["*"]
      }
      conditions = [
        {
          test = "StringEquals"
          variable = "aws:PrincipalAccount"
          values = ["QLTY_AWS_ACCOUNT_ID"]
        },
        {
          test = "StringEquals"
          variable = "aws:ResourceAccount"
          values = ["QLTY_AWS_ACCOUNT_ID"]
        }
      ]
    }
    ```
  </CodeBlock>

  <CodeBlock title="AWS Policy">
    ```json lines theme={"system"}
    {
        "Effect": "Allow",
        "Principal": {
            "AWS": "*"
        },
        "Action": "s3:PutObject",
        "Resource": "*",
        "Condition": {
            "StringEquals": {
                "aws:ResourceAccount": "QLTY_AWS_ACCOUNT_ID",
                "aws:PrincipalAccount": "QLTY_AWS_ACCOUNT_ID"
            }
        }
    }
    ```
  </CodeBlock>
</CodeGroup>

Reach out to [customer support](https://qlty.sh/contact/support) to obtain Qlty's AWS account id.

### Default Branch Coverage Not Displayed

**Symptoms:**

* Banner shows "We've received coverage reports; we haven't yet received a report for your default branch"
* Coverage uploads exist but the project dashboard doesn't display default branch coverage

**Potential Causes and Solutions:**

#### Coverage config not yet merged to default branch

The most common cause is that you've added coverage publishing to your CI config on a feature branch but haven't merged it to your default branch yet. Until the config change is merged, only PR branches will produce coverage uploads. Once you merge the PR that adds coverage publishing to your CI pipeline, subsequent pushes to your default branch will generate coverage uploads and the banner will go away.

#### Default branch also a base branch for a long lived PR

If you have an open pull request where your default branch is the **head** (source) branch (e.g., a long-lived PR from `main` → `production`), some CI providers may inject the PR number into every build on your default branch. This causes Qlty to classify the upload as a pull request upload instead of a branch upload.

You can confirm this by visiting your coverage uploads page and checking whether uploads for your default branch show `refs/pull/XXXX` instead of `refs/heads/<branch>`.

To resolve this, publish coverage a second time on default branch builds using the `--override-pr-number` flag with an empty string. This forces the upload to be classified as a branch upload while preserving PR coverage from the first publish.

Add a second publish step after your existing coverage publish command:

```bash lines theme={"system"}
# First publish (handles PR coverage as usual)
qlty coverage publish <your-existing-flags> <coverage-files>

# Second publish (only on default branch, forces branch classification)
if [ "$CIRCLE_BRANCH" = "main" ]; then
  qlty coverage publish --override-pr-number "" <your-existing-flags> <coverage-files>
fi
```

Replace `main` with your default branch name if different (e.g., `master`).

### Missing Metadata

**Symptoms:**

* Coverage is uploaded but not associated with the correct branch
* Coverage doesn't appear in pull requests
* Coverage data shows with incorrect commit information

**Potential Causes:**

* CI system metadata not detected
* Shallow git clone in CI
* Custom CI setup not recognized by Qlty

**Solutions:**

1. Manually specify metadata with override flags:
   ```bash theme={"system"}
   qlty coverage publish --override-branch=main --override-commit-sha=abcdef123 coverage.xml
   ```
2. Ensure your CI environment provides standard environment variables
3. Use a deeper git clone in CI (or fetch git metadata)
4. Check that the git repository is available in the CI environment

## Viewing Issues

### Coverage Not Showing in GitHub

**Symptoms:**

* No coverage status checks on pull requests
* Missing coverage comments on pull requests
* Coverage data visible in Qlty but not in GitHub

**Potential Causes:**

* GitHub app permissions issues
* Coverage gates not enabled
* PR comments not configured
* Timing issues with CI and status reporting

**Solutions:**

1. Verify GitHub integration settings in project settings
2. Check that coverage gates are enabled in quality gates settings
3. Ensure PR comments are enabled
4. Check GitHub app permissions in your organization settings
5. Try manually uploading coverage for the PR branch

### Inconsistent Coverage Reports

**Symptoms:**

* Coverage fluctuates between builds without code changes

**Potential Causes:**

* Test flakiness or non-deterministic tests
* Cache issues in tests
* Different coverage tool configurations

**Solutions:**
See [Unexpected Coverage Changes](/coverage/unexpected-changes) for a full discussion of possible causes and solutions.

### Missing Coverage for Some Files

**Symptoms:**

* Some files show no coverage data
* Certain directories are missing from coverage reports
* Coverage appears for some languages but not others

**Potential Causes:**

* Include/exclude patterns filtering out files
* Multi-language projects with incomplete coverage setup
* Files not being exercised by tests
* Generated code or third-party code inclusion/exclusion

**Solutions:**

1. Check your coverage tool's include/exclude configuration. See [Excluding Files from Coverage](/coverage/excluding-files) for language-specific examples.
2. Verify that all relevant files are included in coverage report generation. See our documentation on [Incomplete or Missing Coverage Reports](/coverage/unexpected-changes#incomplete-or-missing-coverage-reports) for more detail.
3. Set up coverage for each language in multi-language projects
4. Use multiple coverage reports for different parts of the codebase

## Quality Gate Issues

### Failing Coverage Gates

**Symptoms:**

* Pull requests failing due to coverage checks
* "Coverage decreased" warnings even with improved test coverage
* Diff coverage failing despite high coverage in changed files

**Potential Causes:**

* Thresholds set too high for your project's current state
* Coverage decreasing in files not directly modified
* Base branch coverage calculation issues
* Coverage calculation includes excluded files

**Solutions:**

1. Adjust coverage gate thresholds to realistic levels
2. Investigate [unexpected coverage changes](/coverage/unexpected-changes)
3. Temporarily disable gates while building up coverage
4. [Exclude irrelevant files](/coverage/excluding-files) in your coverage tool so they don't affect gates
5. Focus on diff coverage rather than total coverage for incremental improvement

### Coverage Badges Not Updating

**Symptoms:**

* Outdated coverage percentage in badges
* Coverage badge shows "unknown" or "N/A"
* Badge doesn't reflect recent coverage improvements

**Potential Causes:**

* Badge caching
* No coverage data for default branch
* Badge URL issues

**Solutions:**

1. Ensure coverage is being uploaded for your default branch
2. Check badge URLs and project settings
3. Manually refresh cached badges
4. Verify that the badge is pointing to the correct project and metric
5. Wait for cache expiration (typically a few hours)

## Merging

### Coverage Data Missing

**Presenting Problem**

* Qlty reports less coverage for a source file than expected. For example, a line is covered according to the raw coverage data, but Qlty shows the line as not covered
* Qlty does not show coverage data for a file

**Diagnosis and Resolutions**

1. Ensure that Qlty has received all partial reports (uploads).

   The best diagnostic tool is the list of coverage uploads browsable on qlty.sh at Project Settings => Code Coverage. Search for the commit sha, pull request (e.g. `refs/pull/5`), or branch (e.g. `refs/heads/branchName`). You should see N "incomplete" reports representing the N uploads Qlty received as well as 1 "complete" report, representing a completion of the report. If you see less than you expect, check that:

   * Every upload attempt succeeded. Did the CLI report "Upload successful" at the end of its output? If not, what error occurred?
   * Every coverage report attempted an upload. Providing a unique name with every coverage report (with `--name`) can help pinpoint a missing coverage report. (The name will be show in the coverage upload detail page)
   * Each upload is associated with the same expected tag (or no tag)
   * Investigate [Incomplete or Missing Coverage Reports](/coverage/unexpected-changes#incomplete-or-missing-coverage-reports)

## Coverage Tag Issues

**Symptoms:**

* Tagged coverage not appearing separately
* Incorrect coverage shown for specific tags
* Tags not filtering correctly in UI

**Potential Causes:**

* Incorrect tag specification during upload
* Mixing tagged and untagged uploads
* UI filtering confusion

**Solutions:**

1. Verify tag naming in upload commands:
   ```bash theme={"system"}
   qlty coverage publish --tag=unit coverage.xml
   ```
2. Ensure consistent tag usage across uploads
3. Check tag configuration in project settings
4. Use different tags for different test types (unit, integration, etc.)

## Large Repository Issues

**Symptoms:**

* Coverage uploads timing out
* Very slow coverage rendering in UI
* Missing coverage for some files in large repositories

**Potential Causes:**

* Coverage reports too large
* Too many files included in coverage
* Performance limits in browser extensions

**Solutions:**

1. [Exclude irrelevant files](/coverage/excluding-files) in your coverage tool to limit coverage to relevant code
2. Split large repositories into smaller projects
3. [Exclude generated code, vendor code, or test code](/coverage/excluding-files) from your coverage reports
4. Use more specific coverage focus for very large repositories
5. Contact Qlty support for help with large-scale deployments

## Getting Additional Help

If you've tried the solutions above and are still experiencing issues:

1. **Contact Support**: Reach out to [Qlty support](mailto:support@qlty.sh)
2. **Join Discord**: Ask for help in our [Discord community](https://qlty.sh/discord)
3. **GitHub Issues**: Submit a bug report on our [GitHub issue tracker](https://github.com/qltysh/qlty/issues)

When asking for help, include:

* The exact command you're running
* Any error messages (with sensitive information redacted)
* Your CI provider and configuration
* The coverage tool and language you're using
* Steps you've already taken to troubleshoot
