Skip to content

gocritic panics with "slice out of bounds" #6163

@jh125486

Description

@jh125486

Welcome

  • Yes, I'm using a binary release within 2 latest releases. Only such installations are supported.
  • Yes, I've searched similar issues on GitHub and didn't find any.
  • Yes, I've read the typecheck section of the FAQ.
  • Yes, I've tried with the standalone linter if available (e.g., gocritic, go vet, etc.).
  • I agree to follow this project's Code of Conduct

How did you install golangci-lint?

Brew

Description of the problem

With golangci-lint 2.6.0, gocritic panics with slice of out bounds in dupOptions.

It's been reported and a fix has been released (0.14.1): go-critic/go-critic#1514

Version of golangci-lint

$ golangci-lint --version
golangci-lint has version 2.6.0 built with go1.25.3 from fb09c371 on 2025-10-29T19:41:04Z

Configuration

version: "2"
run:
  tests: true

issues:
  max-issues-per-linter: 0
  max-same-issues: 0

linters:
  default: none
  enable:
    - asciicheck
    - copyloopvar
    - cyclop
    - depguard
    - dogsled
    - durationcheck
    - err113
    - errcheck
    - errorlint
    - exhaustive
    - forbidigo
    - forcetypeassert
    - funlen
    - gochecknoglobals
    - gochecknoinits
    - gocognit
    - goconst
    - gocritic
    - gocyclo
    - gocheckcompilerdirectives
    - goheader
    - gomoddirectives
    - gomodguard
    - goprintffuncname
    - gosec
    - govet
    - importas
    - ineffassign
    - intrange
    - lll
    - makezero
    - misspell
    - mnd
    - nakedret
    - nestif
    - nilerr
    - nlreturn
    - noctx
    - nolintlint
    - paralleltest
    - perfsprint
    - prealloc
    - predeclared
    - protogetter
    - reassign
    - revive
    - rowserrcheck
    - sloglint
    - sqlclosecheck
    - spancheck
    - staticcheck
    - tagalign
    - tagliatelle
    - testpackage
    - thelper
    - tparallel
    - unconvert
    - unparam
    - unused
    - usestdlibvars
    - usetesting
    - wastedassign
    - whitespace
  settings:
    staticcheck:
      checks:
        - "all"
    cyclop:
      max-complexity: 12
    depguard:
      rules:
        nogcommon:
          deny:
            - pkg: github.com/labstack/gommon/log
              desc: Probably an accidental import.
            - pkg: golang.org/x/exp/slog
              desc: Use slog instead.
            - pkg: golang.org/x/net/context
              desc: Use context instead.
            - pkg: github.com/pkg/errors
              desc: Use errors instead.
            - pkg: github.com/golang/protobuf
              desc: Use google.golang.org/protobuf instead.
    exhaustive:
      default-signifies-exhaustive: true
    funlen:
      lines: 100
      statements: 50
    goconst:
      min-len: 2
      min-occurrences: 3
      ignore-calls: false
    gocritic:
      disabled-checks:
        - commentFormatting
        - dupImport
      enabled-tags:
        - diagnostic
        - style
        - performance
        - experimental
        - opinionated
      settings:
        hugeParam:
          sizeThreshold: 512
    gocyclo:
      min-complexity: 12
    godot:
      scope: all
      exclude:
        - ^region .+
        - ^endregion
        - ^ INPUT
        - ^ OUTPUT
        - ^ nop$
        - "^#nosec:"
        - "^ Setup$"
        - "^ Test$"
        - "^ Assert$"
      period: false
      capital: false
    gomoddirectives:
      replace-allow-list:
        - github.com/imdario/mergo
    govet:
      enable-all: true
    lll:
      line-length: 140
    misspell:
      locale: US
    mnd:
      checks:
        - argument
        - case
        - condition
        - operation
        - return
        - assign
      ignored-numbers:
        - "10"
        - "64"
        - "100"
        - "2"
    nlreturn:
      block-size: 4
    nolintlint:
      require-explanation: false
      require-specific: false
    revive:
      rules:
        - name: exported
          severity: warning
    sloglint:
      attr-only: true
      key-naming-case: kebab
      args-on-sep-lines: true
    tagalign:
      order:
        - cmd
        - name
        - short
        - json
        - env
        - type
        - enum
        - default
        - required
        - optional
        - help
      strict: true
    tagliatelle:
      case:
        rules:
          json: snake
          yaml: snake
        use-field-name: true
    unused:
      field-writes-are-uses: false
      exported-fields-are-used: false
  exclusions:
    generated: lax
    presets:
      - comments
      - common-false-positives
      - legacy
      - std-error-handling
    rules:
      - linters:
          - lll
        source: '// '
      - linters:
          - cyclop
          - deadcode
          - dupl
          - err113
          - errcheck
          - exhaustive
          - forcetypeassert
          - funlen
          - gochecknoglobals
          - gocognit
          - gocritic
          - gocyclo
          - gosec
          - govet
          - hugeParam
          - lll
          - nlreturn
          - revive
          - tagliatelle
          - unused
        path: _test\.go
      - linters:
          - lll
        path: fixtures
      - linters:
          - cyclop
          - dupl
          - err113
          - errcheck
          - funlen
          - gochecknoglobals
          - gocognit
          - gocritic
          - gocyclo
          - gosec
          - govet
          - hugeParam
          - lll
          - revive
          - tagliatelle
        path: testhelper
      - linters:
          - goconst
        path: (.+)_test\.go
    paths:
      - pkgs/otelr/otelhttp
      - generated
      - pb
      - third_party$
      - builtin$
      - examples$
      - pkgs/oapi/echoswagger
formatters:
  enable:
    - gci
    - gofmt
    - goimports
  settings:
    gci:
      sections:
        - standard
        - default
        - prefix(<REDACTED>)
    gofmt:
      rewrite-rules:
        - pattern: interface{}
          replacement: any
        - pattern: a[b:len(a)]
          replacement: a[b:]
    goimports:
      local-prefixes:
        - <REDACTED>
  exclusions:
    generated: lax
    paths:
      - pkgs/otelr/otelhttp
      - generated
      - pb/envoyproxy
      - third_party$
      - builtin$
      - examples$

Go environment

$ go version && go env
go version go1.25.3 darwin/arm64
AR='ar'
CC='cc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='c++'
GCCGO='gccgo'
GO111MODULE=''
GOARCH='arm64'
GOARM64='v8.0'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/Users/$USER/Library/Caches/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/Users/$USER/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/f6/49220bzj34j7xw31p0wwg2dc0000gp/T/go-build2249021905=/tmp/go-build -gno-record-gcc-switches -fno-common'
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMOD='/Users/$USER/Code/ap133664-go-monorepo/go.mod'
GOMODCACHE='/Users/$USER/go/pkg/mod'
GONOPROXY='github.com/Fidelity-Red,github.com/Fidelity-Green'
GONOSUMDB='github.com/Fidelity-Red,github.com/Fidelity-Green'
GOOS='darwin'
GOPATH='/Users/a565384/go'
GOPRIVATE=<redacted>
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/opt/homebrew/Cellar/go/1.25.3/libexec'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/Users/$USER/Library/Application Support/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/opt/homebrew/Cellar/go/1.25.3/libexec/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.25.3'
GOWORK=''
PKG_CONFIG='pkg-config'```

</details>

### Verbose output of running

<details>

```console
$ golangci-lint cache clean
$ golangci-lint run -v
INFO golangci-lint has version 2.6.0 built with go1.25.3 from fb09c371 on 2025-10-29T19:41:04Z 
INFO [config_reader] Config search paths: [./ /Users/$USER/Code/<REDACTED> /Users/$USER/Code /Users/$USER /Users /] 
INFO [config_reader] Used config file .golangci.yml 
INFO [config_reader] Module name "github.com/<REDACTED>/<REDACTED>" 
INFO maxprocs: Leaving GOMAXPROCS=14: CPU quota undefined 
INFO [goenv] Read go env for 6.109167ms: map[string]string{"GOCACHE":"/Users/$USER/Library/Caches/go-build", "GOROOT":"/opt/homebrew/Cellar/go/1.25.3/libexec"} 
INFO [lintersdb] Active 66 linters: [asciicheck copyloopvar cyclop depguard dogsled durationcheck err113 errcheck errorlint exhaustive forbidigo forcetypeassert funlen gci gocheckcompilerdirectives gochecknoglobals gochecknoinits gocognit goconst gocritic gocyclo gofmt goheader goimports gomoddirectives gomodguard goprintffuncname gosec govet importas ineffassign intrange lll makezero misspell mnd nakedret nestif nilerr nlreturn noctx nolintlint paralleltest perfsprint prealloc predeclared protogetter reassign revive rowserrcheck sloglint spancheck sqlclosecheck staticcheck tagalign tagliatelle testpackage thelper tparallel unconvert unparam unused usestdlibvars usetesting wastedassign whitespace] 
INFO [loader] Go packages loading at mode 8767 (types_sizes|compiled_files|deps|exports_file|imports|files|name) took 3.27626275s 
INFO [runner/filename_unadjuster] Pre-built 0 adjustments in 92.2305ms 
INFO [linters_context] importas settings found, but no aliases listed. List aliases under alias: key. 
INFO [linters_context/goanalysis] analyzers took 1h2m57.266456475s with top 10 stages: gocritic: 38m13.275383961s, buildir: 2m10.311087311s, goimports: 1m33.305445385s, wastedassign: 1m8.551689494s, unparam: 42.936250164s, gosec: 23.935713046s, fact_deprecated: 16.673405594s, exhaustive: 16.00245817s, unconvert: 15.35503597s, findcall: 14.77448767s 
ERRO [runner] Panic: gocritic: package "handlers" (isInitialPkg: true, needAnalyzeSource: true): runtime error: slice bounds out of range [2:1]: goroutine 1007798 [running]:
runtime/debug.Stack()
        runtime/debug/stack.go:26 +0x64
github.com/golangci/golangci-lint/v2/pkg/goanalysis.(*action).analyzeSafe.func1()
        github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_action.go:55 +0x1d8
panic({0x10579ba20?, 0x14158723f98?})
        runtime/panic.go:783 +0x120
github.com/go-critic/go-critic/checkers.(*dupOptionChecker).getVariadicArgs(0x106348980?, 0x1407c446b80)
        github.com/go-critic/[email protected]/checkers/dupOption_checker.go:79 +0x178
github.com/go-critic/go-critic/checkers.(*dupOptionChecker).VisitExpr(0x140933322a0, {0x105845850?, 0x1407c446b80?})
        github.com/go-critic/[email protected]/checkers/dupOption_checker.go:42 +0x68
github.com/go-critic/go-critic/checkers/internal/astwalk.(*exprWalker).WalkFile.func1({0x10583f940?, 0x1407c446b80?})
        github.com/go-critic/[email protected]/checkers/internal/astwalk/expr_walker.go:25 +0x64
go/ast.inspector.Visit(0x14083b20ea0, {0x10583f940?, 0x1407c446b80?})
        go/ast/walk.go:361 +0x38
go/ast.Walk({0x105838380?, 0x14083b20ea0?}, {0x10583f940, 0x1407c446b80})
        go/ast/walk.go:34 +0x44
go/ast.walkList[...](...)
        go/ast/walk.go:21
go/ast.Walk({0x105838380?, 0x14083b20ea0?}, {0x10583fbe8, 0x1407c446bc0})
        go/ast/walk.go:194 +0x1a30
go/ast.walkList[...](...)
        go/ast/walk.go:21
go/ast.Walk({0x105838380?, 0x14083b20ea0?}, {0x10583f800, 0x141852b50e0})
        go/ast/walk.go:211 +0x1930
go/ast.Walk({0x105838380?, 0x14083b20ea0?}, {0x10583fcb0, 0x1407c446e40})
        go/ast/walk.go:218 +0x1df8
go/ast.walkList[...](...)
        go/ast/walk.go:21
go/ast.Walk({0x105838380?, 0x14083b20ea0?}, {0x10583f800, 0x141852b5170})
        go/ast/walk.go:211 +0x1930
go/ast.Walk({0x105838380?, 0x14083b20ea0?}, {0x10583feb8, 0x141852b51a0})
        go/ast/walk.go:332 +0x5dc
go/ast.Inspect(...)
        go/ast/walk.go:377
github.com/go-critic/go-critic/checkers/internal/astwalk.(*exprWalker).WalkFile(0x140933322b0, 0x1412d43d540)
        github.com/go-critic/[email protected]/checkers/internal/astwalk/expr_walker.go:23 +0x14c
github.com/go-critic/go-critic/linter.(*Checker).Check(...)
        github.com/go-critic/[email protected]/linter/linter.go:160
github.com/golangci/golangci-lint/v2/pkg/golinters/gocritic.runOnFile(0x1414533c000, 0x1412d43d540, {0x140dad58d88, 0x6a, 0x1042bce00?})
        github.com/golangci/golangci-lint/v2/pkg/golinters/gocritic/gocritic.go:146 +0x74
github.com/golangci/golangci-lint/v2/pkg/golinters/gocritic.(*goCriticWrapper).run(0x14000959620, 0x1414533c000)
        github.com/golangci/golangci-lint/v2/pkg/golinters/gocritic/gocritic.go:111 +0x28c
github.com/golangci/golangci-lint/v2/pkg/golinters/gocritic.New.func1(0x10567ee20?)
        github.com/golangci/golangci-lint/v2/pkg/golinters/gocritic/gocritic.go:43 +0x28
github.com/golangci/golangci-lint/v2/pkg/goanalysis.(*action).analyze.func3(...)
        github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_checker.go:183
github.com/golangci/golangci-lint/v2/pkg/goanalysis.(*action).analyze(0x14006436ca0)
        github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_checker.go:209 +0x980
github.com/golangci/golangci-lint/v2/pkg/timeutils.(*Stopwatch).TrackStage(0x140052d8690, {0x104fae461, 0x8}, 0x140095e3700)
        github.com/golangci/golangci-lint/v2/pkg/timeutils/stopwatch.go:111 +0x44
github.com/golangci/golangci-lint/v2/pkg/goanalysis.(*action).analyzeSafe(0x14006436ca0?)
        github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_action.go:59 +0x64
github.com/golangci/golangci-lint/v2/pkg/goanalysis.(*loadingPackage).analyze.func2()
        github.com/golangci/golangci-lint/v2/pkg/goanalysis/runner_loadingpackage.go:111 +0x6c
golang.org/x/sync/errgroup.(*Group).Go.func1()
        golang.org/x/[email protected]/errgroup/errgroup.go:93 +0x4c
created by golang.org/x/sync/errgroup.(*Group).Go in goroutine 3299
        golang.org/x/[email protected]/errgroup/errgroup.go:78 +0x90 
WARN [runner] Can't run linter goanalysis_metalinter: goanalysis_metalinter: gocritic: package "handlers" (isInitialPkg: true, needAnalyzeSource: true): runtime error: slice bounds out of range [2:1] 
INFO [runner/exclusion_paths] Skipped 0 issues by pattern "pkgs/otelr/otelhttp" 
INFO [runner/exclusion_paths] Skipped 0 issues by pattern "generated" 
INFO [runner/exclusion_paths] Skipped 0 issues by pattern "pb" 
INFO [runner/exclusion_paths] Skipped 0 issues by pattern "third_party$" 
INFO [runner/exclusion_paths] Skipped 0 issues by pattern "builtin$" 
INFO [runner/exclusion_paths] Skipped 0 issues by pattern "examples$" 
INFO [runner/exclusion_paths] Skipped 0 issues by pattern "pkgs/oapi/echoswagger" 
INFO [runner/exclusion_rules] Skipped 0 issues by rules: [Path: "examples$", Linters: "gci, gofmt, goimports"] 
INFO [runner/exclusion_rules] Skipped 0 issues by rules: [Source: "// ", Linters: "lll"] 
INFO [runner/exclusion_rules] Skipped 0 issues by rules: [Path: "fixtures", Linters: "lll"] 
INFO [runner/exclusion_rules] Skipped 0 issues by rules: [Path: "(.+)_test\\.go", Linters: "goconst"] 
INFO [runner/exclusion_rules] Skipped 0 issues by rules: [Path: "pb/envoyproxy", Linters: "gci, gofmt, goimports"] 
INFO [runner/exclusion_rules] Skipped 0 issues by rules: [Path: "builtin$", Linters: "gci, gofmt, goimports"] 
INFO [runner/exclusion_rules] Skipped 0 issues by rules: [Path: "_test\\.go", Linters: "cyclop, deadcode, dupl, err113, errcheck, exhaustive, forcetypeassert, funlen, gochecknoglobals, gocognit, gocritic, gocyclo, gosec, govet, hugeParam, lll, nlreturn, revive, tagliatelle, unused"] 
INFO [runner/exclusion_rules] Skipped 0 issues by rules: [Path: "testhelper", Linters: "cyclop, dupl, err113, errcheck, funlen, gochecknoglobals, gocognit, gocritic, gocyclo, gosec, govet, hugeParam, lll, revive, tagliatelle"] 
INFO [runner/exclusion_rules] Skipped 0 issues by rules: [Path: "pkgs/otelr/otelhttp", Linters: "gci, gofmt, goimports"] 
INFO [runner/exclusion_rules] Skipped 0 issues by rules: [Path: "generated", Linters: "gci, gofmt, goimports"] 
INFO [runner/exclusion_rules] Skipped 0 issues by rules: [Path: "third_party$", Linters: "gci, gofmt, goimports"] 
INFO [runner] processing took 49.082µs with stages: exclusion_rules: 36.333µs, exclusion_paths: 11.792µs, max_same_issues: 417ns, nolint_filter: 125ns, max_from_linter: 83ns, path_absoluter: 42ns, source_code: 42ns, path_prettifier: 42ns, fixer: 42ns, uniq_by_line: 41ns, invalid_issue: 41ns, diff: 41ns, sort_results: 41ns, cgo: 0s, filename_unadjuster: 0s, path_shortener: 0s, generated_file_filter: 0s, max_per_file_from_linter: 0s, path_relativity: 0s, severity-rules: 0s 
INFO [runner] linters took 2m51.792590209s with stages: goanalysis_metalinter: 2m51.792510875s 
ERRO Running error: can't run linter goanalysis_metalinter
goanalysis_metalinter: gocritic: package "handlers" (isInitialPkg: true, needAnalyzeSource: true): runtime error: slice bounds out of range [2:1] 
INFO Memory: 1752 samples, avg is 4254.7MB, max is 7461.4MB 
INFO Execution took 2m55.17797775s 

A minimal reproducible example or link to a public repository

I could not reproduce this with a minimal (single file) example. I cannot link to my repo.

Validation

  • Yes, I've included all information above (version, config, etc.).

Supporter

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdependenciesRelates to an upstream dependency

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions