Failed to parse Node.js version sonar-scanner:5.0.1.3006

Hello community,

I have an error when trying to run Sonar scan on my Gitlab-CI. I’m using a docker image with the following components :

[startup.sh] [INFO] Components version:
[startup.sh]     - git:2.40.1
[startup.sh]     - curl:8.5.0
[startup.sh]     - wget:1.21.4
[startup.sh]     - zip:3.0
[startup.sh]     - unzip:6.00
[startup.sh]     - docker:25.0.3
[startup.sh]     - docker-compose:2.17.3
[startup.sh]     - os:Alpine Linux-3.18.3
[startup.sh]     - node:18.17.1
[startup.sh]     - npm:9.6.7
[startup.sh]     - yarn:1.22.19
[startup.sh]     - python:3.11.8
[startup.sh]     - sonar-scanner:5.0.1.3006
[startup.sh]     - dependency-check:8.4.0
[startup.sh]     - os:Alpine Linux-3.18.3
[startup.sh] [END] Initializing container
$ node -v
Using default options for node: --optimize_for_size --expose-gc --gc_interval=100
v18.17.1

Below the Error Stacktrace

INFO: Sensor JavaScript/TypeScript analysis [javascript]
INFO: Detected os: Linux arch: amd64 alpine: true. Platform: UNSUPPORTED
INFO: Using Node.js executable: 'node'.
ERROR: Failed to parse Node.js version, got 'Using default options for node: --optimize_for_size --expose-gc --gc_interval=100v18.17.1'
org.sonar.plugins.javascript.nodejs.NodeCommandException: Failed to parse Node.js version, got 'Using default options for node: --optimize_for_size --expose-gc --gc_interval=100v18.17.1'
    at org.sonar.plugins.javascript.nodejs.NodeCommandBuilderImpl.nodeVersion(NodeCommandBuilderImpl.java:205)
    at org.sonar.plugins.javascript.nodejs.NodeCommandBuilderImpl.checkNodeCompatibility(NodeCommandBuilderImpl.java:181)
    at org.sonar.plugins.javascript.nodejs.NodeCommandBuilderImpl.build(NodeCommandBuilderImpl.java:153)
    at org.sonar.plugins.javascript.bridge.BridgeServerImpl.initNodeCommand(BridgeServerImpl.java:263)
    at org.sonar.plugins.javascript.bridge.BridgeServerImpl.startServer(BridgeServerImpl.java:192)
    at org.sonar.plugins.javascript.bridge.BridgeServerImpl.startServerLazily(BridgeServerImpl.java:303)
    at org.sonar.plugins.javascript.bridge.AbstractBridgeSensor.execute(AbstractBridgeSensor.java:72)
    at org.sonar.scanner.sensor.AbstractSensorWrapper.analyse(AbstractSensorWrapper.java:64)
    at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:88)
    at org.sonar.scanner.sensor.ModuleSensorsExecutor.lambda$execute$1(ModuleSensorsExecutor.java:61)
    at org.sonar.scanner.sensor.ModuleSensorsExecutor.withModuleStrategy(ModuleSensorsExecutor.java:79)
    at org.sonar.scanner.sensor.ModuleSensorsExecutor.execute(ModuleSensorsExecutor.java:61)
    at org.sonar.scanner.scan.SpringModuleScanContainer.doAfterStart(SpringModuleScanContainer.java:82)
    at org.sonar.core.platform.SpringComponentContainer.startComponents(SpringComponentContainer.java:201)
    at org.sonar.core.platform.SpringComponentContainer.execute(SpringComponentContainer.java:180)
    at org.sonar.scanner.scan.SpringProjectScanContainer.scan(SpringProjectScanContainer.java:398)
    at org.sonar.scanner.scan.SpringProjectScanContainer.scanRecursively(SpringProjectScanContainer.java:394)
    at org.sonar.scanner.scan.SpringProjectScanContainer.doAfterStart(SpringProjectScanContainer.java:363)
    at org.sonar.core.platform.SpringComponentContainer.startComponents(SpringComponentContainer.java:201)
    at org.sonar.core.platform.SpringComponentContainer.execute(SpringComponentContainer.java:180)
    at org.sonar.scanner.bootstrap.SpringGlobalContainer.doAfterStart(SpringGlobalContainer.java:139)
    at org.sonar.core.platform.SpringComponentContainer.startComponents(SpringComponentContainer.java:201)
    at org.sonar.core.platform.SpringComponentContainer.execute(SpringComponentContainer.java:180)
    at org.sonar.batch.bootstrapper.Batch.doExecute(Batch.java:71)
    at org.sonar.batch.bootstrapper.Batch.execute(Batch.java:65)
    at org.sonarsource.scanner.api.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:46)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60)
    at jdk.proxy1/jdk.proxy1.$Proxy0.execute(Unknown Source)
    at org.sonarsource.scanner.api.EmbeddedScanner.doExecute(EmbeddedScanner.java:189)
    at org.sonarsource.scanner.api.EmbeddedScanner.execute(EmbeddedScanner.java:138)
    at org.sonarsource.scanner.cli.Main.execute(Main.java:126)
    at org.sonarsource.scanner.cli.Main.execute(Main.java:81)
    at org.sonarsource.scanner.cli.Main.main(Main.java:62)
INFO: Hit the cache for 0 out of 0
INFO: Miss the cache for 0 out of 0
INFO: Sensor JavaScript/TypeScript analysis [javascript] (done) | time=1598ms
INFO: Sensor JavaScript inside HTML analysis [javascript]
INFO: Hit the cache for 0 out of 0
INFO: Miss the cache for 0 out of 0
INFO: Sensor JavaScript inside HTML analysis [javascript] (done) | time=1ms
INFO: Sensor CSS Rules [javascript]
INFO: Sensor CSS Rules is restricted to changed files only
INFO: No CSS, PHP, HTML or VueJS files are found in the project. CSS analysis is skipped.

The error is thrown by the method nodeVersion(String versionString) in the class NodeCommandBuilderImpl.java (see SonarJS/sonar-plugin/sonar-javascript-plugin/src/main/java/org/sonar/plugins/javascript/nodejs/NodeCommandBuilderImpl.java at master · SonarSource/SonarJS · GitHub)
because it’s trying to parse the sentence

Using default options for node: --optimize_for_size --expose-gc --gc_interval=100
v18.17.1

rather than

v18.17.1

  static Version nodeVersion(String versionString) throws NodeCommandException {
    Matcher versionMatcher = NODEJS_VERSION_PATTERN.matcher(versionString);
    if (versionMatcher.lookingAt()) {
      return Version.create(
        Integer.parseInt(versionMatcher.group(1)),
        Integer.parseInt(versionMatcher.group(2)),
        Integer.parseInt(versionMatcher.group(3))
      );
    } else {
      throw new NodeCommandException(
        "Failed to parse Node.js version, got '" + versionString + "'"
      );
    }
  }

Is there any solution to fix this ?

Hi,

Welcome to the community and thanks for this report and your investigation!

Just to dot the i’s, what version of SonarQube are you using? I assume it’s 10.4.1?

 
Thx,
Ann

Hello Ann,

We are using the Enterprise Edition Version 10.3

In SonarJS/sonar-plugin/sonar-javascript-plugin/src/main/java/org/sonar/plugins/javascript/nodejs/NodeCommandBuilderImpl.java at master · SonarSource/SonarJS · GitHub

changing

  private static final Pattern NODEJS_VERSION_PATTERN = Pattern.compile(
    "v?(\\d+)\\.(\\d+)\\.(\\d+)"
  );

to

  private static final Pattern NODEJS_VERSION_PATTERN = Pattern.compile(
    ".*v?([1-9]\\d+)\\.(\\d+)\\.(\\d+)"
  );

should work probably !

Tests

/* Online Java Compiler and Editor */
import java.util.regex.Matcher;
import java.util.regex.Pattern;

class NodeCommandException extends RuntimeException {

    public NodeCommandException(String message) {
        super(message);
    }

    public NodeCommandException(String message, Throwable cause) {
        super(message, cause);
    }
}

public class HelloSonar {

    private static final Pattern NODEJS_VERSION_PATTERN = Pattern.compile(
                ".*v?([1-9]\\d+)\\.(\\d+)\\.(\\d+)"
            );

    static void nodeVersion(String versionString) throws NodeCommandException {
        Matcher versionMatcher = NODEJS_VERSION_PATTERN.matcher(versionString);
        
        if (versionMatcher.lookingAt()) {
            System.out.println(versionMatcher.group(1));
            System.out.println(versionMatcher.group(2));
            System.out.println(versionMatcher.group(3));
        } else {
            throw new NodeCommandException(
                "Failed to parse Node.js version, got '" + versionString + "'"
            );
        }
    }

    public static void main(String []args) {
        String input = new String("Using default options for node--optimize_for_size --expose-gc --gc_interal=100v18.17.1");
        HelloSonar.nodeVersion(input);
    }
}

Outputs :

18
17
1

Hi,

Can you upgrade to 10.4.1 and make sure this is still replicable?

 
Ann

The code is the same in 10.4.1 I don’t think this would change anything !

1 Like

Hello @Anas_Khouja,

thank you for reporting this. Indeed your fix would work. I will create a PR with it. Can I ask where does this version come from? Is this some custom-built node binary? We’ve never seen that in the stdout:

Using default options for node: --optimize_for_size --expose-gc --gc_interval=100
v18.17.1

Cheers,
Victor