View on GitHub


Documentation for check-spelling

Each event should be listed in the Action Log.

ℹ️ As of v0.0.20, workflows can configure whether specific events are treated as ❌Errors or ⚠️Warnings.


Warning: reffy.js:27:4 ... 17, Warning - compatilibity is not a recognized word. (unrecognized-spelling) Warning: src/browserlib/extract-dfns.mjs:159:11 ... 20, Warning - hyperlink is not a recognized word. (unrecognized-spelling)

The token isn't in the dictionary



Warning: bridge/client/app/_models/metadata.ts:1:1 ... 1, Warning - Skipping bridge/client/app/_models/metadata.ts because there seems to be more noise (6) than unique words (3) (total: 6 / 7). (noisy-file)

This generally means that the file doesn't appear to be English.

Technically it means there are fewer unique dictionary words in the file than unique non-word tokens.

ℹ️ Info: Feature: Autodetect noisy files



Warning: .github/actions/spelling/patterns.txt:5:1 ... 9, Warning - bad regex (bad-regex)

Perl 5 didn't like your regular expression.

The log should actually provide a more detailed message from Perl.

You can testing your pattern with Regular Expression Test Page for Perl.

The tool generally doesn't apply flags that significantly modify evaluation (it might apply /g).


This means that you used a tool that didn't include a newline at the end of your text file.

Unix tools get quite upset and confused by this.

(git) diff and patch get frustrated and will yield odd jitter markings because of it.

wc -l will not treat the last line of your file as a file (an off by one error of sorts).


echo >> file

Or open it in a text editor that will fix it for you (vi, nano, ...).


Dictionary entries are composed of 26 letters (a-z in both uppercase and lowercase), apostrophe ('), and a newline (\n).

Words are generally at least 3 characters long. (This is tunable.)

If you include any other characters (including -), the entry will be ignored.

This is mostly a matter of pragmatism. You might be worried that the tool doesn't know the color sea-green, that's ok, the tool doesn't see sea-green, it ignores the - and sees the words sea and green, and unless you remove one or both of those words from its dictionary (using reject.txt), it will accept both.

Since it doesn't see sea-green as a single word, trying to add sea-green to your dictionary won't work.


If you want to accept avii-ridge in your repository, you can:


Warning: .github/actions/spelling/expect.txt:1:5 ... 6, Warning - entry has unexpected whitespace (whitespace-in-dictionary)

This generally means you have a mix of DOS and Unix line endings.

The tool generally assumes it's only going to see Unix line endings.


Use dos2unix.


dos2unix .github/actions/spelling/expect.txt


This may be renamed to unexpected-line-ending in the future.


Warning: .github/actions/spelling/expect.txt:1:5 ... 6, Warning - entry has unexpected whitespace (whitespace-in-dictionary)

This generally means you have a mix of DOS and Unix line endings.

The tool generally assumes it's only going to see Unix line endings.


Use dos2unix.


dos2unix .github/actions/spelling/expect.txt


Warning: ... 59, Warning - patterns patterns matches an objections.patterns entry. (forbidden-pattern)

This is generated by Forbidden patterns.

The repository has a specific regular expression defining a pattern that it doesn't want used.

⚠️ Currently each hit will be logged whereas unrecognized-spelling will trigger limited-references. This will probably change, possibly before v0.0.20.


Identify the pattern and either rewrite your code not to match it, or adjust the pattern not to match your code.


Over time, features will be deprecated. Typically a replacement will be available. Eventually support for the deprecated feature will be removed.


Please try to migrate to the newer supported item.


Warning: ... 0, Warning - size 10000000 exceeds limit 1000000. (large-file)

This is generated by Configurable file size limits.


If you want to check the file, you can adjust the file size limit.

If the file should be skipped, please add it to excludes.txt.


Warning: pkg/testutil/testutil_windows.go:26:67 ... 69, Warning - amd is not a recognized word-- found 80 times. (limited-references)

This is generated when a word appears more than unknown_word_limit times.


If the item is a word, add it to expect or allow.

If the item should be masked with a pattern, add a matching pattern.

If the file(s) containing it shouldn't be checked, add patterns to skip them to excludes.

If the item is misspelled, fixing the reported instances will disclose additional instances. You could of course use your local tools to find the remaining instances.


Test the url manually. What to do will depend on the error code from the web server.

503 (internal server error)

Failed to retrieve cspell:r/src/r.txt ( HTTP/2 503 server: Varnish retry-after: 0


Rerun the workflow.

check-spelling v0.0.22 will include code to retry these failures.

404 (file not found)

Error: Failed to retrieve cspell:software-terms/softwareTerms.txt -- (dictionary-not-found)

This can happen if a path to a dictionary is incorrect.

The most common case is when upgrading versions of check-spelling. Newer versions may use refreshed versions of the cspell: dictionaries and their dictionaries are reorganized periodically.



🪄 Recommended Solution

You can simply remove the dictionary reference(s) and remove (if present):

    check_extra_dictionaries: ''

This will let check-spelling suggest new dictionaries.


You can browse through the current dictionaries and identify suitable replacements. The output will show a URL which includes a repository and tag (e.g. check-spelling/cspell-dicts/v20220814), you can thus browse to That might be something like (although you should consider which dictionary/dictionaries are relevant to your repository):


Use older dictionaries

If you want to continue to use the previous dictionaries, you can check the run output of a previous version of check-spelling for the with: output, e.g.:

    dictionary_source_prefixes: {"cspell": ""}

and specify the single dictionary directly (by expanding any url prefixes, e.g. cspell: appropriately), e.g.:

-      cspell:software-terms/softwareTerms.txt

You could also copy over the prefix into your configuration, but note that check_extra_dictionaries will probably not match, so using:

    dictionary_source_prefixes: '{"cspell": ""}'

Will result in the same warning, but it will be non-fatal:

Failed to retrieve cspell:public-licenses/src/generated/public-licenses.txt -- (dictionary-not-found)

Use multiple prefixes

In order to retain the check_extra_dictionaries behavior, while still retaining the old dictionary reference, and without having long urls in extra_dictionaries, you can add additional prefixes to dictionary_source_prefixes.

In this example, the default for dictionary_source_prefixes is {"cspell": ""} and the previous default was {"cspell": ""}. By changing the previous default's prefix to cspell0 and copying over the current default, it's possible to use dictionaries from both and a manner that might be slightly easier to read:

+    dictionary_source_prefixes: '
+      {
+        "cspell": "",
+        "cspell0": ""
+      }'
-      cspell:software-terms/softwareTerms.txt
+      cspell0:software-terms/softwareTerms.txt


Notice: src/Stack/Build/Source.hs:214:1 ... 1, Notice - Line matches candidate pattern (?:^|[\t ,"'=(])-[DPWXYLlf](?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,})` (candidate-pattern)

The report will also include an entry like:

# hit-count: 169 file-count: 40
# Compiler flags
(?:^|[\t ,"'`=(])-[DPWXYLlf](?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,})

The line in question is:

    , concat [["-fhpc"] | isLocal && toCoverage (boptsTestOpts bopts)]

👩‍🔬 In a version after 0.0.20, as part of Suggest patterns, you can provide a candidate.patterns file.

If a line in a file (that isn't excluded), and after being filtered for patterns has word-like items that aren't in the dictionary, then those lines will be checked against candidate patterns. Each candidate will report separately against each line.

If a candidate pattern appeals to you, you can (tinker with, and) add it to patterns.

Simple comment lines # preceding a candidate line will be included in the output for candidates in the comment in the report.

In order to give users a chance to understand how useful a given candidate is, a couple of lines that match each pattern are reported. Version 0.0.22 will highlight the matching part of the line when SARIF reporting is enabled.


You can add the pattern into patterns.txt:

 hit-count: 169 file-count: 40
 Compiler flags
(?:^|[\t ,"'`=(])-[DPWXYLlf](?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,})

Or, if you've decided that the candidate pattern doesn't make sense for the repository, you can remove it from or comment it out in the candidate.patterns file.


spell_check_this expects a repository and revision of the form owner/repository@revision

If the revision you selected doesn't work, feel free to file a bug with a public example (it's certainly possible the pattern is too strict).


only_check_changed_files and use_sarif

You can choose one or the other. By default, check-spelling favors the former. If you want to use the latter, you'll have to turn off the former.

use_sarif and security-events: write

To upload sarif results, use_sarif needs security-events: write.


If you want to use sarif, add:

  security-events: write

to the job that contains the use_sarif configuration.

Alternatively, you can remove use_sarif: ... from the job in which case the classic error reporting mechanism will be used.

use_sarif and private repositories

GitHub SARIF processing requires GitHub Advanced Security to be enabled.

This is possible for Public repositories on and for Enterprise Repositories, but it's possible that you can't use it with Private repositories on


use_sarif and act

You can try setting GITHUB_TOKEN.

This isn't supported and is unlikely to work.

Eventually provisions will be made to generally expose the artifact itself. There is an artifact server which could help....


The file has really long lines. It's probably minified.



This can happen if you have the same entry multiple times in extra_dictionaries.


Remove duplicate entries. check-spelling will ignore duplicate instances.


Nothing on the internet is guaranteed to be 💯% reliable. Sometimes a server will be unable to offer content.

Unfortunately, most programs have required content and won't work without it. If you see this message, e.g.:

Failed to download (to /tmp/tmp.PqDJv9CiN8) (required-download-failed)

Then you've run into a case where check-spelling needed a resource (here, the dictionary), and the server it asked returned an error.

Because the dictionary is required in order to determine whether things are misspelled, check-spelling gave up.


Most of the time, this will be a transient error, you can click the Re-run jobs drop down and select Re-run failed jobs.

It's possible that your workflow is misconfigured and is pointing to a resource that doesn't exist (whether because it was removed or someone made an error), in which case you'll have to identify a correct URL and update the workflow.

If the version of check-spelling was recently upgraded (this can happen if you're using @main, especially if you're using @prerelease, or if you're using another action which wraps check-spelling), then it's possible that the configuration is now referencing a version of a resource that doesn't exist.


Failed to retrieve cspell:bash/bash-words.txt -- (dictionary-not-found)

Between v20220816 and v20230502, a number of the dictionaries were renamed, mostly changing from foo/bar.txt to foo/dict/bar.txt, so, for this one, cspell:bash/bash-words.txt would become cspell:bash/dict/bash-words.txt.


If you have enabled Check filenames and paths with check_file_names: 1, then in addition to checking the contents of files, check-spelling will check the file paths.

A reported item will correspond to a portion of a file path, possibly a folder, possibly a file name, or possibly the file extension. Initially, a bunch of the items listed will be false positives, but it's quite possible that one or two of them will be misspellings.

Error: .github/workflows/graphql-inspector.yml:1:9 ... 18, Error - `workflows` is not a recognized word. (check-file-path)
Error: .github/workflows/graphql-inspector.yml:1:37 ... 40, Error - `yml` is not a recognized word. (check-file-path)

In the log form, the numbers 9 ... 18 refer to character offsets within the file path. Here 9 ... 18 refers to workflows and 37 ... 40 refer to yml for the same file path.

Identifying the problematic items


For false positives, you can add entries to expect.txt or allow.txt (this is an especially good idea if you're using a term as a term of art, e.g. graphql) just as if the items were found in the files themselves, or add patterns to patterns.txt.

If the file / directory is misspelled, you'll need to use git mv to rename it.


check-spelling tries to find "words" in your repository that it doesn't have in the dictionaries you've configured. It does that by applying heuristics to identify word boundaries. It also allows you to apply patterns to mask portions of lines. Most likely as a result of some patterns in the configuration, it found a "word" that wasn't in the dictionary, but when it looked through the line w/o applying the patterns, it couldn't determine where the word was.

Most of the time, the fault is in pattern definitions, especially patterns that consume part of a word.

⚠️ If this flags to the first line of a file and you have check_file_names enabled, it's possible it's warning about the file path as opposed to the line. A distinct warning will probably be added for this case at a later time.



When producing a Summary Table, if sections would cause the Summary to exceed its size limit, they'll be dropped.


Remove items


When processing a file, if the time to parse exceeds the splitter_timeout environment variable, parsing will stop.



check-spelling looks for items not in the dictionary, once it finds them, it checks those items against the expect file. If words are in expect (and found), they will be used to cover additional variations (variants). If a word is covered by a base word, then it doesn't need to be explicitly listed again by its variant, and check-spelling will warn you about the superfluous entry.

English / programming have interesting ways of handling proper nouns.

In general, a term might be written as MICROSOFT, it's reasonable to decide that this is ok for use in a project. Doing this doesn't tend to mean that using Microsoft or microsoft would be acceptable.

OTOH, once you've decided that Microsoft is acceptable, it's likely that you'll also accept MICROSOFT (e.g. as a constant or in some ALL CAPS SENTENCE) while still not allowing microsoft.

If you decide that microsoft is acceptable, then it's likely that you'll also accept Microsoft (e.g. as the first word in a sentence).

expect.txt is parsed with the assumption that only the most general form that's found in your code is listed.

Similarly, if you use the term widgit, you might write it in a plural as widgits. If you include widgit in expect, you don't need to include widgits as check-spelling will assume that you are ok with that plural.



Check Spelling works by reviewing files and identifying problems with them. You can configure which files it should check by using excludes and only



Check filenames and paths results in a list of file paths to be checked as if it was the contents of a file. The general noisy-file heuristic has triggered on the file list itself.



In v0.0.22, if a file contains utf16 surrogates, it'll be flagged.

check-spelling is designed for utf-8 based files, so a file containing a utf-16 surrogate should be a reasonably good indication that the file won't contain content check-spelling can handle.



If you encounter this, then check-spelling's Sarif module misbehaved. Sorry about that.


Please file a bug.


A Block Ignore rule's start pattern matched content in the file, but the corresponding end tag wasn't found.

As a result, all content after the begin tag was ignored.

Note that this feature is experimental, it's possible you've encountered a bug.



A Block Ignore rule's start pattern matched content in the file, but the corresponding end tag wasn't found.

As a result, all content after the begin tag was ignored.

Note that this feature is experimental, it's possible you've encountered a bug.



A Block Ignore rule's start pattern matched content in the file, but the corresponding end tag wasn't found.

As a result, all content after the begin tag was ignored.

Note that this feature is experimental, it's possible you've encountered a bug.



The suppress_push_for_open_pull_request configuration expects there to be an on: containing pull_request or pull_request_target -- if it isn't found, there wouldn't be a place for check-spelling to run.

Instead of leaving users without a run, the suppress_push_for_open_pull_request configuration will be ignored.


FAQ | Showcase | Event descriptions | Configuration information | Known Issues | Possible features | Deprecations | Release notes | Helpful scripts