A golangci-lint module plugin that detects string-based path and URL concatenation in Go code, suggesting path.Join, filepath.Join, or url.JoinPath instead.
| Pattern | Example | Suggestion |
|---|---|---|
String concat with "/" or "\\" |
a + "/" + b |
path.Join(a, b) |
fmt.Sprintf with path separators |
fmt.Sprintf("%s/%s", a, b) |
path.Join(a, b) |
strings.Join with "/" or "\\" |
strings.Join(parts, "/") |
path.Join(parts...) |
The suggested function depends on context:
- With
require-path-context: derived from the consumer function's package (os.Open→filepath.Join,http.Get→url.JoinPath) - Without: inferred from file imports (
net/url→url.JoinPath,path/filepath→filepath.Join, otherwisepath.Join)
- Connection strings:
fmt.Sprintf("postgres://%s:%s@%s/%s", ...)is not flagged - Scheme prefixes:
"https://" + hostis not flagged (unlesscheck-scheme-concatis enabled) - Ignored strings: Configurable substrings (e.g.
/attr/,/value/) that indicate domain-specific identifier construction rather than path building
Requires golangci-lint v2 with the module plugin system.
version: v2.8.0
plugins:
- module: github.com/jakedoublev/pathconcat
version: v0.3.0linters:
enable:
- pathconcat
settings:
custom:
pathconcat:
type: module
description: "Detects string path/URL concatenation"
settings:
# Optional: suppress findings where any literal contains these substrings
ignore-strings:
- "/attr/"
- "/value/"
# Optional: flag "https://" + host scheme concatenation
# check-scheme-concat: true
# Optional: only flag when result flows into os.Open, http.Get, etc.
# require-path-context: truegolangci-lint custom # builds ./custom-gcl with the plugin
./custom-gcl run ./... # run linting| Setting | Type | Default | Description |
|---|---|---|---|
ignore-strings |
[]string |
[] |
Substrings that suppress diagnostics. If any string literal in a concatenation chain or fmt.Sprintf format string contains one of these, the finding is skipped. |
check-scheme-concat |
bool |
false |
When true, also flags scheme prefix concatenation like "https://" + host. By default these are not flagged. |
require-path-context |
bool |
false |
When true, only flags concatenation when the result flows into a known path/URL-consuming function (os.Open, http.Get, filepath.Join, url.Parse, etc.). Uses SSA analysis. Reduces false positives at the cost of missing indirect usage. |
Use the standard //nolint:pathconcat directive:
resource := p[1] + "/" + p[2] //nolint:pathconcat // reconstructing gRPC procedure pathMIT