Skip to content

dupword appears to rewrite a raw multi-line SQL string literal during auto-fix. #70

Description

@wingmans

Summary

dupword appears to rewrite a raw multi-line SQL string literal during auto-fix.

This was observed when running dupword via golangci-lint, with dupword enabled as the only linter and all formatters disabled.

Environment

  • golangci-lint: golangci-lint has version 2.12.1 built with go1.26.2 from 9aa24e9 on 2026-05-01T16:06:44Z
  • dupword: enabled through golangci-lint
  • Go: go version go1.26.2 darwin/arm64
  • OS: macOS

Minimal repro

go.mod

module dupword-repro

go 1.24

repro.go

package main

func createQuery() string {
    const q = `
INSERT INTO addresses (
  contact_id,
  address_type_id,
  line1,
  line2,
  city,
  region,
  postal_code,
  country,
  is_deleted,
  version,
  created_at,
  updated_at,
  deleted_at
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 0, 1, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL);
`

    return q
}

func main() {
    _ = createQuery()
}

.golangci.yml

version: "2"

linters:
  default: none
  enable:
    - dupword

formatters:
  enable: []

Command

golangci-lint run ./... --fix --issues-exit-code=0

Expected

The raw multi-line string should remain unchanged, or any fix should preserve string semantics.

Actual

dupword --fix rewrites the raw SQL string literal.

In the original project this resulted in the SQL being rewritten into an interpreted one-line string, which also made the source much less readable.

Notes

This was isolated by bisecting enabled auto-fix linters. The rewrite happens with dupword alone enabled, and does not happen with gofmt, gofumpt, or goimports.

Diff

index 219f8d3..4f25256 100644
--- a/repro.go
+++ b/repro.go
@@ -1,23 +1,7 @@
 package main
 
 func createQuery() string {
-       const q = `
-INSERT INTO addresses (
-  contact_id,
-  address_type_id,
-  line1,
-  line2,
-  city,
-  region,
-  postal_code,
-  country,
-  is_deleted,
-  version,
-  created_at,
-  updated_at,
-  deleted_at
-) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 0, 1, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, NULL);
-`
+       const q = "\nINSERT INTO addresses (\n  contact_id,\n  address_type_id,\n  line1,\n  line2,\n  city,\n  region,\n  postal_code,\n  country,\n  is_deleted,\n  version,\n  created_at,\n  updated_at,\n  deleted_at\n) VALUES (?, ?, 0, 1, CURRENT_TIMESTAMP, "
 
        return q

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions