{"record":{"id":"c42e9f76c28345d1","repo":"google/tsunami-security-scanner","slug":"error-loading-config","errorCode":null,"errorMessage":"Error loading config.","messagePattern":"Error loading config\\.","errorType":"exception","errorClass":"LinkageError","httpStatus":null,"severity":"critical","filePath":"main/src/main/java/com/google/tsunami/main/cli/TsunamiCli.java","lineNumber":338,"sourceCode":"  private static TsunamiConfig loadConfig() {\n    try (ScanResult scanResult = new ClassGraph().enableAllInfo().scan()) {\n      ConfigLoader configLoader;\n      Optional<String> loaderClass = TsunamiConfig.getSystemProperty(\"tsunami.config.loader\");\n      if (loaderClass.isPresent()\n          && scanResult.getAllClassesAsMap().containsKey(loaderClass.get())) {\n        configLoader =\n            scanResult\n                .getClassInfo(loaderClass.get())\n                .loadClass(ConfigLoader.class)\n                .getConstructor()\n                .newInstance();\n      } else {\n        configLoader = new YamlConfigLoader();\n      }\n\n      return configLoader.loadConfig();\n    } catch (ReflectiveOperationException e) {\n      throw new LinkageError(\"Error loading config.\", e);\n    }\n  }\n}\n","sourceCodeStart":320,"sourceCodeEnd":342,"githubUrl":"https://github.com/google/tsunami-security-scanner/blob/363ba87b3543f8ae8e4304d3416818f03da7f262/main/src/main/java/com/google/tsunami/main/cli/TsunamiCli.java#L320-L342","documentation":"TsunamiCli.loadConfig() wraps any ReflectiveOperationException thrown while instantiating/using the config loader in a LinkageError with message 'Error loading config.'. The original exception (e.g. ClassNotFoundException for a custom config class) is attached as the cause.","triggerScenarios":"Passing --config-loader pointing to a class that is not on the classpath, or a config class whose constructor reflection fails, so ClassLoader.loadClass / newInstance inside loadConfig (TsunamiCli.java:338) throws ReflectiveOperationException.","commonSituations":"Typo in the custom config-loader class name; custom class packaged in a jar not on the runtime classpath; class exists but lacks the expected no-arg constructor or visibility.","solutions":["Read the 'Caused by' of the LinkageError to see the real reflective failure.","Verify the --config-loader class is fully qualified and present on the classpath.","Ensure the class implements the expected loader interface (e.g. extends YamlConfigLoader) and has an accessible no-arg constructor.","If no custom loader is needed, drop the flag so the default YamlConfigLoader is used."],"exampleFix":"// before\n--config-loader=com.example.MissingConfigLoader\n// after\n--config-loader=com.example.config.MyConfigLoader  # present on classpath, extends YamlConfigLoader","handlingStrategy":"try-catch","validationCode":"Class.forName(\"com.example.MyConfigLoader\"); // fails fast if not on classpath","typeGuard":null,"tryCatchPattern":"try { cli.run(args); } catch (LinkageError e) { log.error(\"Config loading failed\", e.getCause()); }","preventionTips":["Always inspect the cause chain of LinkageError.","Fully qualify custom config-loader class names and ship them on the classpath.","Smoke-test custom configs in CI."],"tags":["cli","reflection","classpath","java"],"backgroundTag":"class-not-found","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"}