Need help with gometalinter?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

3.6K Stars 280 Forks MIT License 448 Commits 0 Opened issues



Services available


Need anything else?

Contributors list

Go Meta Linter

gometalinter is DEPRECATED and the project will be archived on 2019-04-07. See #590 for discussion.

Switch to golangci-lint.

Build Status Gitter chat

The number of tools for statically checking Go source for errors and warnings is impressive.

This is a tool that concurrently runs a whole bunch of those linters and normalises their output to a standard format:

::[]:  ()


stutter.go:9::warning: unused global variable unusedGlobal (varcheck)
stutter.go:12:6:warning: exported type MyStruct should have comment or be unexported (golint)

It is intended for use with editor/IDE integration.


Binary Releases

To install the latest stable release:

curl -L | sh

Alternatively you can install a specific version from the releases list.


brew tap alecthomas/homebrew-tap
brew install gometalinter

Editor integration

Supported linters

  • go vet - Reports potential errors that otherwise compile.
  • go tool vet --shadow - Reports variables that may have been unintentionally shadowed.
  • gotype - Syntactic and semantic analysis similar to the Go compiler.
  • gotype -x - Syntactic and semantic analysis in external test packages (similar to the Go compiler).
  • deadcode - Finds unused code.
  • gocyclo - Computes the cyclomatic complexity of functions.
  • golint - Google's (mostly stylistic) linter.
  • varcheck - Find unused global variables and constants.
  • structcheck - Find unused struct fields.
  • maligned - Detect structs that would take less memory if their fields were sorted.
  • errcheck - Check that error return values are used.
  • staticcheck - Statically detect bugs, both obvious and subtle ones.
  • dupl - Reports potentially duplicated code.
  • ineffassign - Detect when assignments to existing variables are not used.
  • interfacer - Suggest narrower interfaces that can be used.
  • unconvert - Detect redundant type conversions.
  • goconst - Finds repeated strings that could be replaced by a constant.
  • gosec - Inspects source code for security problems by scanning the Go AST.

Disabled by default (enable with

  • testify - Show location of failed testify assertions.
  • test - Show location of test failures from the stdlib testing module.
  • gofmt -s - Checks if the code is properly formatted and could not be further simplified.
  • goimports - Checks missing or unreferenced package imports.
  • gochecknoinits - Report init functions, to reduce side effects in code.
  • gochecknoglobals - Report global vars, to reduce side effects in code.
  • lll - Report long lines (see
  • misspell - Finds commonly misspelled English words.
  • nakedret - Finds naked returns.
  • unparam - Find unused function parameters.
  • safesql - Finds potential SQL injection vulnerabilities.

Additional linters can be added through the command line with

(see below).

Configuration file

gometalinter now supports a JSON configuration file called

that can be placed at the root of your project. The configuration file will be automatically loaded from the working directory or any parent directory and can be overridden by passing
or ignored with
. The format of this file is determined by the
struct in config.go.

The configuration file mostly corresponds to command-line flags, with the following exceptions:

  • Linters defined in the configuration file will overlay existing definitions, not replace them.
  • "Enable" defines the exact set of linters that will be enabled (default linters are disabled).
    displays the list of default linters with the exact names you must use.

Here is an example configuration file:

  "Enable": ["deadcode", "unconvert"]

If a

file is loaded, individual options can still be overridden by passing command-line flags. All flags are parsed in order, meaning configuration passed with the
flag will override any command-line flags passed before and be overridden by flags passed after.


The default

key places the different fields of an
into a template. this corresponds to the
option command-line flag.


Format: "{{.Path}}:{{.Line}}:{{if .Col}}{{.Col}}{{end}}:{{.Severity}}: {{.Message}} ({{.Linter}})"

Format Methods

  • {{.Path.Relative}}
    - equivalent to
    which outputs a relative path to the file
  • {{.Path.Abs}}
    - outputs an absolute path to the file

Adding Custom linters

Linters can be added and customized from the config file using the

field. Linters supports the following fields:
  • Command
    - the path to the linter binary and any default arguments
  • Pattern
    - a regular expression used to parse the linter output
  • IsFast
    - if the linter should be run when the
    flag is used
  • PartitionStrategy
    - how paths args should be passed to the linter command:
    • directories
      - call the linter once with a list of all the directories
    • files
      - call the linter once with a list of all the files
    • packages
      - call the linter once with a list of all the package paths
    • files-by-package
      - call the linter once per package with a list of the files in the package.
    • single-directory
      - call the linter once per directory

The config for default linters can be overridden by using the name of the linter.

Additional linters can be configured via the command line using the format



$ gometalinter --linter='vet:go tool vet -printfuncs=Infof,Debugf,Warningf,Errorf:PATH:LINE:MESSAGE' .

Comment directives

gometalinter supports suppression of linter messages via comment directives. The form of the directive is:

// nolint[: [, , ...]]

Suppression works in the following way:

  1. Line-level suppression

    A comment directive suppresses any linter messages on that line.

    eg. In this example any messages for

    a := 10
    will be suppressed and errcheck messages for
    defer r.Close()
    will also be suppressed.
    a := 10 // nolint
    a = 2
    defer r.Close() // nolint: errcheck
  2. Statement-level suppression

    A comment directive at the same indentation level as a statement it immediately precedes will also suppress any linter messages in that entire statement.

    eg. In this example all messages for

    will be suppressed.
    // nolint
    func SomeFunc() {

Implementation details: gometalinter now performs parsing of Go source code, to extract linter directives and associate them with line ranges. To avoid unnecessary processing, parsing is on-demand: the first time a linter emits a message for a file, that file is parsed for directives.


Install gometalinter (see above).

Run it:

$ cd example
$ gometalinter ./...
stutter.go:13::warning: unused struct field MyStruct.Unused (structcheck)
stutter.go:9::warning: unused global variable unusedGlobal (varcheck)
stutter.go:12:6:warning: exported type MyStruct should have comment or be unexported (golint)
stutter.go:16:6:warning: exported type PublicUndocumented should have comment or be unexported (golint)
stutter.go:8:1:warning: unusedGlobal is unused (deadcode)
stutter.go:12:1:warning: MyStruct is unused (deadcode)
stutter.go:16:1:warning: PublicUndocumented is unused (deadcode)
stutter.go:20:1:warning: duplicateDefer is unused (deadcode)
stutter.go:21:15:warning: error return value not checked (defer a.Close()) (errcheck)
stutter.go:22:15:warning: error return value not checked (defer a.Close()) (errcheck)
stutter.go:27:6:warning: error return value not checked (doit()           // test for errcheck) (errcheck)
stutter.go:29::error: unreachable code (vet)
stutter.go:26::error: missing argument for Printf("%d"): format reads arg 1, have only 0 args (vet)

Gometalinter also supports the commonly seen

recursive path format. Note that this can be very slow, and you may need to increase the linter
to allow linters to complete.


Exit status

gometalinter sets two bits of the exit status to indicate different issues:

| Bit | Meaning |-----|---------- | 0 | A linter generated an issue. | 1 | An underlying error occurred; eg. a linter failed to execute. In this situation a warning will also be displayed.

eg. linter only = 1, underlying only = 2, linter + underlying = 3

What's the best way to use
in CI?

There are two main problems running in a CI:

  1. Linters break, causing
    gometalinter --install --update
    to error
    (this is no longer an issue as all linters are vendored).
  2. gometalinter
    adds a new linter.

I have solved 1 by vendoring the linters.

For 2, the best option is to disable all linters, then explicitly enable the ones you want:

gometalinter --disable-all --enable=errcheck --enable=vet --enable=vetshadow ...

How do I make
work with Go 1.5 vendoring?

has a
flag that just sets
, however the underlying tools must support it. Ensure that all of the linters are up to date and built with Go 1.5 (
gometalinter --install --force
) then run
gometalinter --vendor .
. That should be it.

Why does
gometalinter --install
install a fork of gocyclo?

I forked

because the upstream behaviour is to recursively check all subdirectories even when just a single directory is specified. This made it unusably slow when vendoring. The recursive behaviour can be achieved with gometalinter by explicitly specifying
. There is a pull request open.

Many unexpected errors are being reported

If you see a whole bunch of errors being reported that you wouldn't expect, such as compile errors, this typically means that something is wrong with your Go environment. Try

go install
and fix any issues with your go installation, then try gometalinter again.

Gometalinter is not working

That's more of a statement than a question, but okay.

Sometimes gometalinter will not report issues that you think it should. There are three things to try in that case:

1. Update to the latest build of gometalinter and all linters

curl -L | sh

If you're lucky, this will fix the problem.

2. Analyse the debug output

If that doesn't help, the problem may be elsewhere (in no particular order):

  1. Upstream linter has changed its output or semantics.
  2. gometalinter is not invoking the tool correctly.
  3. gometalinter regular expression matches are not correct for a linter.
  4. Linter is exceeding the deadline.

To find out what's going on run in debug mode:

gometalinter --debug

This will show all output from the linters and should indicate why it is failing.

3. Report an issue.

Failing all else, if the problem looks like a bug please file an issue and include the output of

gometalinter --debug

How do I filter issues between two git refs?

revgrep can be used to filter the output of

to show issues on lines that have changed between two git refs, such as unstaged changes, changes in
and between
. See the project's documentation and
usage for more information.
go get -u
gometalinter |& revgrep               # If unstaged changes or untracked files, those issues are shown.
gometalinter |& revgrep               # Else show issues in the last commit.
gometalinter |& revgrep master        # Show issues between master and HEAD (or any other reference).
gometalinter |& revgrep origin/master # Show issues that haven't been pushed.

Checkstyle XML format

supports checkstyle compatible XML output format. It is triggered with
gometalinter --checkstyle

Checkstyle format can be used to integrate gometalinter with Jenkins CI with the help of Checkstyle Plugin.

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.