Skip to content

swiftlint crashes due to duplicate keys in configuration #6052

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
2 tasks done
dimlio opened this issue Apr 15, 2025 · 4 comments
Open
2 tasks done

swiftlint crashes due to duplicate keys in configuration #6052

dimlio opened this issue Apr 15, 2025 · 4 comments
Assignees
Labels
bug Unexpected and reproducible misbehavior.

Comments

@dimlio
Copy link

dimlio commented Apr 15, 2025

New Issue Checklist

Bug Description

Swiftlint crashes while trying to read .swiftlint.yml with duplicating keys in sub-directory.

$ find .
.
./subdir
./subdir/.swiftlint.yml
./subdir/a.swift
$ cat subdir/.swiftlint.yml 
opt_in_rules:
  - closure_body_length

opt_in_rules:
  - closure_body_length
$ ~/GitHub/SwiftLint/.build/debug/swiftlint
Linting Swift files in current working directory
The operation couldn’t be completed. (SwiftLintCore.Issue error 15.)
Could not read configuration: file Configuration.swift, line 289
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Abort trap: 6 (core dumped)
$ ~/GitHub/SwiftLint/.build/debug/swiftlint --version
0.59.0

If I run swiftlint in subdirectory it correctly reports an error:

$ cd subdir/
$ ~/GitHub/SwiftLint/.build/debug/swiftlint 
warning: Cannot parse YAML file: error: parser: expected all keys to be unique but found the following duplicated key(s):
opt_in_rules ([1:1, 4:1]):
opt_in_rules:
^
opt_in_rules:
^ – Falling back to default configuration
Linting Swift files in current working directory
Linting 'a.swift' (1/1)
Done linting! Found 0 violations, 0 serious in 1 file.

Stacktrace:

thread #2
    frame #0: 0x000000018e4f0388 libsystem_kernel.dylib`__pthread_kill + 8
    frame #1: 0x000000018e52988c libsystem_pthread.dylib`pthread_kill + 296
    frame #2: 0x000000018e432cf0 libsystem_c.dylib`__abort + 132
    frame #3: 0x000000018e432c6c libsystem_c.dylib`abort + 136
    frame #4: 0x000000010312be78 swiftlint`queuedFatalError(string="Could not read configuration", file="SwiftLintFramework/Configuration.swift", line=289) at QueuedPrint.swift:61:5
    frame #5: 0x00000001031ba218 swiftlint`Configuration.init(configurationFiles=1 value, enableAllRules=false, onlyRule=0 values, cachePath=nil, ignoreParentAndChildConfigs=true, mockedNetworkResults=0 key/value pairs, useDefaultConfigOnFailure=nil) at Configuration.swift:289:17
    frame #6: 0x00000001031a1148 swiftlint`Configuration.configuration(directory=Swift.String @ 0x000000016d5ec730) at Configuration+Merging.swift:117:38
    frame #7: 0x00000001031a0c70 swiftlint`implicit closure #2 in implicit closure #1 in Configuration.configuration() at Configuration+Merging.swift:88:61
    frame #8: 0x00000001031a177c swiftlint`thunk for @callee_guaranteed (@guaranteed String) -> (@owned Configuration) at <compiler-generated>:0
    frame #9: 0x00000001031a17c4 swiftlint`partial apply for thunk for @callee_guaranteed (@guaranteed String) -> (@owned Configuration) at <compiler-generated>:0
    frame #10: 0x00000001028c1704 swiftlint`Optional.map<String, B>(_:) at <compiler-generated>:0
    frame #11: 0x00000001031a0a94 swiftlint`Configuration.configuration(file=0x00006000019a41e0) at Configuration+Merging.swift:88:57
    frame #12: 0x000000010318c788 swiftlint`closure #1 in Configuration.groupFiles(file=0x00006000019a41e0) at Configuration+CommandLine.swift:115:37
    frame #13: 0x00000001030f2e64 swiftlint`Array.filterGroup<SwiftLintCore.SwiftLintFile>(transform=0x1031902bc) at Array+SwiftLint.swift:76:26
    frame #14: 0x00000001030f3698 swiftlint`Array.parallelFilterGroup<SwiftLintCore.SwiftLintFile>(transform=0x1031902bc) at Array+SwiftLint.swift:93:20
    frame #15: 0x0000000103188f20 swiftlint`Configuration.groupFiles(files=1 value, visitor=SwiftLintFramework.LintableFilesVisitor @ 0x0000000116827840) at Configuration+CommandLine.swift:114:22
    frame #16: 0x0000000103188b28 swiftlint`closure #2 in Configuration.visitLintableFiles(, files=1 value, visitor=SwiftLintFramework.LintableFilesVisitor @ 0x0000000116827840) at Configuration+CommandLine.swift:82:17
    frame #17: 0x0000000103188b98 swiftlint`partial apply for closure #2 in Configuration.visitLintableFiles(with:storage:) at <compiler-generated>:0
    frame #18: 0x00000001031fc5dc swiftlint`static Signposts.record<[SwiftLintFramework.Configuration : [SwiftLintCore.SwiftLintFile]]>(name="Configuration.VisitLintableFiles.GroupFiles", span=timeline, body=0x103188b78) at Signposts.swift:32:26
    frame #19: 0x0000000103186848 swiftlint`Configuration.visitLintableFiles(visitor=SwiftLintFramework.LintableFilesVisitor @ 0x0000000116833348, storage=0x00006000017bd740) at Configuration+CommandLine.swift:81:42
    frame #20: 0x0000000103190854 swiftlint`Configuration.visitLintableFiles(options=SwiftLintFramework.LintOrAnalyzeOptions @ 0x000000011681f840, cache=0x00006000039bc680, storage=0x00006000017bd740, visitorBlock=0x0000000104003b88 async function pointer to partial apply forwarder for closure #1 (SwiftLintFramework.CollectedLinter) async -> () in static SwiftLintFramework.LintOrAnalyzeCommand.collectViolations(builder: SwiftLintFramework.LintOrAnalyzeResultBuilder) async throws -> Swift.Array<SwiftLintCore.SwiftLintFile>) at Configuration+CommandLine.swift:293:26
    frame #21: 0x00000001031cd6a4 swiftlint`static LintOrAnalyzeCommand.collectViolations(builder=0x00000001371060a0) at LintOrAnalyzeCommand.swift:163:48
    frame #22: 0x00000001031cca3c swiftlint`static LintOrAnalyzeCommand.lintOrAnalyze(options=SwiftLintFramework.LintOrAnalyzeOptions @ 0x0000000137810620) at LintOrAnalyzeCommand.swift:144:31
    frame #23: 0x00000001031cbb70 swiftlint`closure #1 in static LintOrAnalyzeCommand.run(options=SwiftLintFramework.LintOrAnalyzeOptions @ 0x0000000137810620) at LintOrAnalyzeCommand.swift:138:68
    frame #24: 0x00000001031cbc78 swiftlint`partial apply for closure #1 in static LintOrAnalyzeCommand.run(_:) at <compiler-generated>:0
    frame #25: 0x00000001031fcea0 swiftlint`static Signposts.record<()>(name="LintOrAnalyzeCommand.run", span=timeline, body=0x104003b40) at Signposts.swift:63:32
    frame #26: 0x00000001031cb868 swiftlint`static LintOrAnalyzeCommand.run(options=SwiftLintFramework.LintOrAnalyzeOptions @ 0x0000000137810918) at LintOrAnalyzeCommand.swift:137:29
    frame #27: 0x0000000103c22afc swiftlint`SwiftLint.Lint.run() at Lint.swift:63:44
    frame #28: 0x0000000103c257f8 swiftlint`protocol witness for AsyncParsableCommand.run() in conformance SwiftLint.Lint at <compiler-generated>:0
    frame #29: 0x00000001028cb8cc swiftlint`static AsyncParsableCommand.main(arguments=nil) at AsyncParsableCommand.swift:41:32
    frame #30: 0x00000001028cbbf0 swiftlint`static AsyncParsableCommand.main() at AsyncParsableCommand.swift:61:16
    frame #31: 0x0000000103c412bc swiftlint`static SwiftLint.$main() at SwiftLint.swift:9:1
    frame #32: 0x0000000103c4182c swiftlint`async_MainTQ0_ at SwiftLint.swift:10:8
    frame #33: 0x0000000103c41950 swiftlint`thunk for @escaping @convention(thin) @async () -> () at <compiler-generated>:0
    frame #34: 0x0000000103c41a78 swiftlint`partial apply for thunk for @escaping @convention(thin) @async () -> () at <compiler-generated>:0

At least 0.57.0 doesn't crash, so looks like recent regression.
I tried to bisect but stuck due to:

$ git bisect good
Bisecting: 135 revisions left to test after this (roughly 7 steps)
[7421e24fc281d73d4c37550f95054751b4fc0f8f] Use action to extract binary from Docker image
$ swift build
Fetching https://github.com/ileitch/swift-filename-matcher
Updating https://github.com/jpsim/SourceKitten.git
Updating https://github.com/drmohundro/SWXMLHash.git
...
Downloading binary artifact https://github.com/realm/SwiftLint/releases/download/0.57.1/SwiftLintBinary.artifactbundle.zip
error: failed downloading 'https://github.com/realm/SwiftLint/releases/download/0.57.1/SwiftLintBinary.artifactbundle.zip' which is required by binary target 'SwiftLintBinary': badResponseStatusCode(404)

Environment

  • SwiftLint version (run swiftlint version to be sure)
    0.59.0

  • Installation method used (Homebrew, CocoaPods, building from source, etc)
    Built from source.

  • Configuration file:

opt_in_rules:
  - closure_body_length

opt_in_rules:
  - closure_body_length
@SimplyDanny SimplyDanny added the bug Unexpected and reproducible misbehavior. label Apr 15, 2025
@jayeshkawli
Copy link

jayeshkawli commented Apr 16, 2025

👍 We are also having this issue. Full error log here

[07:14:44]: $ swiftlint lint --config .swiftlint.yml > ./fastlane/swiftlint.report.json
[07:14:45]: ▸ The operation couldn’t be completed. (SwiftLintCore.Issue error 15.)
[07:14:45]: ▸ Could not read configuration: file Configuration.swift, line 289
[07:14:45]: ▸ sh: line 1: 37588 Abort trap: 6           swiftlint lint --config .swiftlint.yml > ./fastlane/swiftlint.report.json
[07:14:45]: 
[07:14:45]: SwiftLint finished with exit code 0, which would normally fail the build.
[07:14:45]: fastlane will continue because the `ignore_exit_status` option was used! 🙈

Happening in 0.59.1

@jayeshkawli
Copy link

jayeshkawli commented Apr 16, 2025

Actually never mind. We had fault in our config file. But I still think error reporting could be better to not throw us off on the wrong path.

@mildm8nnered
Copy link
Collaborator

I think there are a few things going on here

Firstly, we call abort() intentionally on a fatal error, although this isn't the most graceful exit.

Secondly, we're getting the default The operation couldn’t be completed. (SwiftLintCore.Issue error 15.) message in some cases, because Issue does not implement errorDescription correctly - the result should be optional.

@mildm8nnered
Copy link
Collaborator

See also #5284 for an example of where exiting abnormally may not be ideal

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Unexpected and reproducible misbehavior.
Projects
None yet
Development

No branches or pull requests

4 participants