-
Notifications
You must be signed in to change notification settings - Fork 27
Description
Contact Details
No response
What happened?
The Checkmarx CLI intermittently crashes with a concurrent map access error when setting configuration properties. This is a race condition between the main thread writing to the Viper configuration map and a signal handler goroutine reading from it simultaneously.
Environment
- CLI Version: 2.3.29 (likely affects other versions)
- OS: Linux (ubuntu-latest on GitHub Actions)
- Architecture: x86_64
- Command:
cx configure set --prop-name cx_base_uri --prop-value https://eu-2.ast.checkmarx.net/
Error Message
fatal error: concurrent map read and map write
goroutine 9 [running]:
internal/runtime/maps.fatal({0x2bc805b?, 0xc0008d6b00?})
/Users/runner/hostedtoolcache/go/1.24.4/x64/src/runtime/panic.go:1058 +0x18
github.com/spf13/viper.(*Viper).searchMap(0xc00001a300, 0x13?, {0xc000067540, 0x1, 0x1})
/Users/runner/go/pkg/mod/github.com/spf13/viper@v1.20.1/viper.go:478 +0x53
Stack Trace Analysis
The crash occurs due to concurrent access to a Viper configuration map:
- Main goroutine (goroutine 1): Writing config via
setConfigPropertyQuiet()
at configuration.go:111 - Signal handler (goroutine 9): Reading config via
signalHandler()
at main.go:192
Steps to Reproduce
- Install Checkmarx CLI v2.3.29
- Run configuration commands (commonly in CI/CD automation):
./cx configure set --prop-name cx_base_uri --prop-value "https://eu-2.ast.checkmarx.net/"
./cx configure set --prop-name cx_client_id --prop-value "YOUR_CLIENT_ID"
./cx configure set --prop-name cx_client_secret --prop-value "YOUR_SECRET"
./cx configure set --prop-name cx_tenant --prop-value "YOUR_TENANT"
- The crash occurs intermittently (race condition timing-dependent)
Note: This commonly happens in GitHub Actions when running multiple configure set
commands sequentially
Expected Behavior
Configuration properties should be set successfully without crashes.
Actual Behavior
Intermittent crashes with "concurrent map read and map write" error.
Workaround
Re-run the command - the race condition doesn't trigger every time.
Suggested Fix
Use proper synchronization for the Viper configuration map access:
- Use
sync.RWMutex
to protect map access - Or use
sync.Map
for concurrent-safe operations - Or ensure signal handler doesn't access config during writes
Impact
- CI/CD pipelines fail intermittently
- Requires manual re-runs
- Reduces confidence in automation
Additional Information
- Full stack trace available at: https://github.com/midnightntwrk/midnight-indexer/actions/runs/17270855592/job/49014936439#step:10:128
- The issue is reproducible in GitHub Actions environments
- Affects multiple organizations using the CLI in automation
Related Code
The issue appears to be in:
/internal/wrappers/configuration/configuration.go:111
(setConfigPropertyQuiet)/cmd/main.go:192
(signalHandler)/internal/commands/util/configuration.go:122
(runSetValue function)
All access Viper configuration without proper synchronization.
Version
2.3.29
Operating System & Version
Other
Specify Other OS Version
ubuntu-latest on GitHub Actions
Relevant log output
## Full Stack Trace
<details>
<summary>Click to expand full stack trace</summary>
fatal error: concurrent map read and map write
goroutine 9 [running]:
internal/runtime/maps.fatal({0x2bc805b?, 0xc0008d6b00?})
/Users/runner/hostedtoolcache/go/1.24.4/x64/src/runtime/panic.go:1058 +0x18
github.com/spf13/viper.(*Viper).searchMap(0xc00001a300, 0x13?, {0xc000067540, 0x1, 0x1})
/Users/runner/go/pkg/mod/github.com/spf13/viper@v1.20.1/viper.go:478 +0x53
github.com/spf13/viper.(*Viper).find(0xc00001a300, {0x2b8d8b0, 0x13}, 0x1)
/Users/runner/go/pkg/mod/github.com/spf13/viper@v1.20.1/viper.go:1163 +0x1d9
github.com/spf13/viper.(*Viper).Get(0xc00001a300, {0x2b8d8b0?, 0x0?})
/Users/runner/go/pkg/mod/github.com/spf13/viper@v1.20.1/viper.go:713 +0x49
github.com/spf13/viper.(*Viper).GetString(0x0?, {0x2b8d8b0?, 0x0?})
/Users/runner/go/pkg/mod/github.com/spf13/viper@v1.20.1/viper.go:788 +0x18
github.com/spf13/viper.GetString(...)
/Users/runner/go/pkg/mod/github.com/spf13/viper@v1.20.1/viper.go:785
main.signalHandler(0xc000157810)
/Users/runner/work/ast-cli/ast-cli/cmd/main.go:192 +0x3b
created by main.exitListener in goroutine 1
/Users/runner/work/ast-cli/ast-cli/cmd/main.go:186 +0x96
goroutine 1 [runnable]:
github.com/spf13/viper.(*Viper).WriteConfig(0xc00001a300)
/Users/runner/go/pkg/mod/github.com/spf13/viper@v1.20.1/viper.go:1584 +0x3e
github.com/spf13/viper.WriteConfig(...)
/Users/runner/go/pkg/mod/github.com/spf13/viper@v1.20.1/viper.go:1577
github.com/checkmarx/ast-cli/internal/wrappers/configuration.setConfigPropertyQuiet({0x7fff58301b9d, 0xb}, {0x7fff58301bb6?, 0x5?})
/Users/runner/work/ast-cli/ast-cli/internal/wrappers/configuration/configuration.go:111 +0x72
github.com/checkmarx/ast-cli/internal/wrappers/configuration.SetConfigProperty({0x7fff58301b9d, 0xb}, {0x7fff58301bb6, 0x1f})
/Users/runner/work/ast-cli/ast-cli/internal/wrappers/configuration/configuration.go:120 +0x10e
github.com/checkmarx/ast-cli/internal/commands/util.NewConfigCommand.runSetValue.func3(0xc0008b4308, {0xc00078e0c0?, 0x0?, 0x2b5e4b2?})
/Users/runner/work/ast-cli/ast-cli/internal/commands/util/configuration.go:122 +0xa9
</details>