Skip to content

ctxbackground precision: isContextBackgroundCall matches identifier name "context" syntactically while the same file detects the [Content truncated due to length] #38789

@github-actions

Description

@github-actions

Summary

The ctxbackground analyzer detects the context.Context parameter of the enclosing function via package type-identity (correct), but detects the context.Background() call by comparing the bare identifier name to the string "context" (syntactic, no pass.TypesInfo). The two halves of the same linter use different rigor, which is both an internal inconsistency and a precision bug.

Evidence — pkg/linters/ctxbackground/ctxbackground.go

Call detection is purely syntactic (line 86):

func isContextBackgroundCall(call *ast.CallExpr) bool {
	sel, ok := call.Fun.(*ast.SelectorExpr)
	if !ok { return false }
	ident, ok := sel.X.(*ast.Ident)
	if !ok { return false }
	return ident.Name == "context" && sel.Sel.Name == "Background"   // <-- name-only match
}

Meanwhile parameter detection in the same file is type-identity based (lines 94, 103, 118-128):

ctxType := contextType(pass)            // scans pass.Pkg.Imports() for path "context"
...
if !types.Identical(t, ctxType) { continue }

Impact (latent, both directions)

  • False positive: any local variable, field, or shadowing receiver named context with a Background() method (e.g. a custom context struct value) is matched. ident.Name == "context" does not verify the identifier resolves to the imported context package.
  • False negative: an aliased import import ctxpkg "context" followed by ctxpkg.Background() is not matched, because the identifier name is ctxpkg, not context.

This mirrors the sortslice precision fix that landed in #38029, and the package-aware helper astutil.IsFmtErrorf. ctxbackground is unenforced (~30 candidate sites), so this is a safe, latent-only precision fix.

Recommendation

Resolve the selector's base identifier to the context package via the type system instead of by name, reusing the file's existing contextType(pass) import-scan pattern:

func isContextBackgroundCall(pass *analysis.Pass, call *ast.CallExpr) bool {
	sel, ok := call.Fun.(*ast.SelectorExpr)
	if !ok || sel.Sel.Name != "Background" { return false }
	ident, ok := sel.X.(*ast.Ident)
	if !ok { return false }
	pkgName, ok := pass.TypesInfo.ObjectOf(ident).(*types.PkgName)
	return ok && pkgName.Imported().Path() == "context"
}

(Thread pass into the call site at the top of run.) Add testdata: a ctxpkg "context" aliased import (must flag) and a local context value with a Background() method (must not flag).

Validation checklist

  • Aliased import ctxpkg "context" + ctxpkg.Background() is now reported.
  • A non-package identifier named context with a Background() method is NOT reported.
  • Existing positive/negative testdata still pass.
  • go test ./pkg/linters/ctxbackground/... passes.

Effort: Small — single function signature + testdata; matches the landed #38029 template.

References

Generated by 🤖 Sergo - Serena Go Expert · 290.8 AIC · ⌖ 12.6 AIC · ⊞ 6.3K ·

  • expires on Jun 18, 2026, 9:28 PM UTC-08:00

Metadata

Metadata

Assignees

No one assigned

    Labels

    cookieIssue Monster Loves Cookies!sergo

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions