---
title: "QA checks"
description: "Look up the model-free checks that decide whether a machine translation is accepted."
canonical_url: "https://diglot.sh/machine-translation/qa-checks"
---
# QA checks

> Look up the model-free checks that decide whether a machine translation is accepted.

A language model can return text that looks fine and still breaks a page. `runQa` catches the failures that can be detected without a model, so every machine translation is checked in the same way, whichever model produced it.

```ts
import { runQa } from '@diglot/mt'

const issues = runQa(translation, segment, { locale: 'fr', glossary, style })
```

It returns a list of `{ check, severity, message }`. An `error` rejects the output and triggers a retry. A `warning` is accepted and reported for reviewers.

## Checks

<table>
<thead>
  <tr>
    <th>
      Check
    </th>
    
    <th>
      Severity
    </th>
    
    <th>
      Rule
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        grammar
      </code>
    </td>
    
    <td>
      error
    </td>
    
    <td>
      <code>
        validate
      </code>
      
       from <code>
        @diglot/core
      </code>
      
       passes: no markup outside the <a href="https://diglot.sh/core/validation">
        translation grammar
      </a>
      
      , and plain segments stay plain
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        placeholders
      </code>
    </td>
    
    <td>
      error, warning
    </td>
    
    <td>
      Every placeholder is present and paired. Repeated code placeholders are a warning. Text shaped like a placeholder (<code>
        ｛1｝
      </code>
      
      , <code>
        [1]
      </code>
      
      , <code>
        <1>
      </code>
      
      , <code>
        $1
      </code>
      
      ) that the source doesn't have is an error
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        untranslated
      </code>
    </td>
    
    <td>
      error, warning
    </td>
    
    <td>
      Output identical to a source with three or more translatable words is an error. Output that is mostly source words is a warning
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        length-ratio
      </code>
    </td>
    
    <td>
      warning
    </td>
    
    <td>
      The length falls outside the band for the locale
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        leaked-instructions
      </code>
    </td>
    
    <td>
      error
    </td>
    
    <td>
      Words such as "translation", "placeholder", "voici la", code fences or JSON keys that the source doesn't have
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        structure
      </code>
    </td>
    
    <td>
      error, warning
    </td>
    
    <td>
      Heading markers in a heading are an error. A changed line count is a warning
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        numbers
      </code>
    </td>
    
    <td>
      error, warning
    </td>
    
    <td>
      Version strings and multi-digit numbers must be kept (error). Single digits are a warning
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        emphasis
      </code>
    </td>
    
    <td>
      error, warning
    </td>
    
    <td>
      Emphasis markers that cannot open or close under CommonMark flanking rules, such as <code>
        _
      </code>
      
       inside a word or <code>
        **
      </code>
      
       between punctuation and CJK text. A warning when the source has such markers too
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        glossary
      </code>
    </td>
    
    <td>
      warning
    </td>
    
    <td>
      See <a href="https://diglot.sh/machine-translation/glossary-and-style">
        Glossary and style
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        response
      </code>
    </td>
    
    <td>
      error
    </td>
    
    <td>
      The model's answer lacks the segment or doesn't match the schema
    </td>
  </tr>
</tbody>
</table>

Glossary terms that are kept untranslated don't count as source words in the `untranslated` check.

## Length bands

The `length-ratio` check compares the length of the translation with the source, ignoring placeholders and extra whitespace, and applies only to sources of 25 characters or more. The default bands are:

<table>
<thead>
  <tr>
    <th>
      Language
    </th>
    
    <th>
      Range
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        fr
      </code>
      
      , <code>
        es
      </code>
      
      , <code>
        it
      </code>
      
      , <code>
        pt
      </code>
    </td>
    
    <td>
      0.85 to 1.7
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        de
      </code>
    </td>
    
    <td>
      0.85 to 1.8
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ru
      </code>
    </td>
    
    <td>
      0.8 to 1.7
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ja
      </code>
    </td>
    
    <td>
      0.25 to 0.9
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        zh
      </code>
    </td>
    
    <td>
      0.2 to 0.8
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ko
      </code>
    </td>
    
    <td>
      0.3 to 1
    </td>
  </tr>
</tbody>
</table>

Other languages have no default band. Set `lengthRatio` in `<locale>/style.yml` to add or change one.

## What happens to issues

[`translateSegments`](https://diglot.sh/machine-translation/translate-segments) and [`updateTranslation`](https://diglot.sh/machine-translation/update-translation) retry on errors and reject after the last attempt. The [Action](https://diglot.sh/workflow/action/rejected-and-skipped) stores the error messages of rejected segments in `.diglot/rejected/<locale>.json`.


## Sitemap

See the full [sitemap](https://diglot.sh/sitemap.md) for all pages.
