{"record":{"id":"7ee4eeaef7b096fb","repo":"google/tsunami-security-scanner","slug":"number-of-plugin-server-paths-must-be-equal-to-number-of","errorCode":null,"errorMessage":"Number of plugin server paths must be equal to number of plugin server ports. Paths: %s. Ports: %s.","messagePattern":"Number of plugin server paths must be equal to number of plugin server ports\\. Paths: (.+?)\\. Ports: (.+?)\\.","errorType":"validation","errorClass":"ParameterException","httpStatus":null,"severity":"error","filePath":"main/src/main/java/com/google/tsunami/main/cli/LanguageServerOptions.java","lineNumber":98,"sourceCode":"            int port = Integer.parseInt(pluginServerPort);\n            if (!(port <= NetworkEndpointUtils.MAX_PORT_NUMBER && port > 0)) {\n              throw new ParameterException(\n                  String.format(\n                      \"Port out of range. Expected [0, %s], actual %s.\",\n                      NetworkEndpointUtils.MAX_PORT_NUMBER, pluginServerPort));\n            }\n          } catch (NumberFormatException e) {\n            throw new ParameterException(\n                String.format(\"Port number must be an integer. Got %s instead.\", pluginServerPort),\n                e);\n          }\n        }\n      }\n\n      var pathCounts = pluginServerFilenames == null ? 0 : pluginServerFilenames.size();\n      var portCounts = pluginServerPorts == null ? 0 : pluginServerPorts.size();\n      if (pathCounts != portCounts) {\n        throw new ParameterException(\n            String.format(\n                \"Number of plugin server paths must be equal to number of plugin server ports.\"\n                    + \" Paths: %s. Ports: %s.\",\n                pathCounts, portCounts));\n      }\n\n      if (!pluginServerRpcDeadlineSeconds.isEmpty()) {\n        if (pluginServerRpcDeadlineSeconds.size() != pathCounts) {\n          throw new ParameterException(\n              String.format(\n                  \"Number of plugin server rpc deadlines must be equal to number of plugin server\"\n                      + \" ports. Paths: %s. Ports: %s. Deadlines: %s\",\n                  pathCounts, portCounts, pluginServerRpcDeadlineSeconds.size()));\n        }\n      }\n    }\n\n    if (!remotePluginServerAddress.isEmpty()) {","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/google/tsunami-security-scanner/blob/363ba87b3543f8ae8e4304d3416818f03da7f262/main/src/main/java/com/google/tsunami/main/cli/LanguageServerOptions.java#L80-L116","documentation":"Each plugin server filename is paired positionally with a port, so validate() requires pluginServerFilenames.size() == pluginServerPorts.size(). A count mismatch means the pairing is ambiguous and throws this ParameterException.","triggerScenarios":"Running Tsunami with e.g. two --plugin-server-filename values but one --plugin-server-port value, or forgetting one flag of the pair entirely.","commonSituations":"Adding a new language plugin server and updating only one of the two flags, or commented-out lines in generated configs that remove one entry but not the other.","solutions":["Provide the same number of --plugin-server-filename and --plugin-server-port values, in matching order.","Count the flag occurrences in your launch script/config and align them.","If adding a server, add both its path and port together."],"exampleFix":"// before\n--plugin-server-filename=a.py --plugin-server-filename=b.py --plugin-server-port=8080\n// after\n--plugin-server-filename=a.py --plugin-server-filename=b.py --plugin-server-port=8080 --plugin-server-port=8081","handlingStrategy":"validation","validationCode":"if (filenames.size() != ports.size()) { throw new IllegalStateException(\"path/port count mismatch\"); }","typeGuard":null,"tryCatchPattern":"try { options.validate(); } catch (ParameterException e) { log.error(\"Pairing mismatch: {}\", e.getMessage()); }","preventionTips":["Always update filename and port flags together.","Generate both flags from one list of server definitions.","Count flag occurrences in launch scripts before running."],"tags":["cli","configuration","count-mismatch"],"backgroundTag":"conflicting-config-options","analyzedSha":"363ba87b3543f8ae8e4304d3416818f03da7f262","analyzedAt":"2026-09-13T01:50:53.990Z","contentChangedAt":"2026-09-13T01:50:53.990Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}