{"record":{"id":"b14c511363117702","repo":"NationalSecurityAgency/ghidra","slug":"multiple-settings-for","errorCode":null,"errorMessage":"Multiple settings for: ","messagePattern":"Multiple settings for: ","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/ServerConfig.java","lineNumber":704,"sourceCode":"\n\t\tString line;\n\t\tConfigLine parse = new ConfigLine();\n\n\t\ttry {\n\t\t\tfor (;;) {\n\t\t\t\tline = reader.readLine();\n\t\t\t\tif (line == null) {\n\t\t\t\t\tbreak;\t\t// End of file reached\n\t\t\t\t}\n\t\t\t\tif (line.length() != 0) {\n\t\t\t\t\tparse.parseUptoKey(line);\n\t\t\t\t\tif (parse.key == null) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tString curval = keyValue.get(parse.key);\t\t// Check if this is a key we want to find\n\t\t\t\t\tif (curval != null) {\t\t\t\t\t\t// If this line is setting a value we control\n\t\t\t\t\t\tif (curval.length() != 0) {\n\t\t\t\t\t\t\tthrow new IOException(\"Multiple settings for: \" + parse.key);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tparse.parseValue(line);\t\t// Discard the original value, but preserve any comment\n\t\t\t\t\t\tif (parse.status == 1) {\t// We have uncommented controlled key\n\t\t\t\t\t\t\tkeyValue.put(parse.key, parse.value);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfinally {\n\t\t\treader.close();\n\t\t}\n\t}\n\n\t/**\n\t * Read in all the entries of the connection file\n\t * @param inFile the file to read in\n\t * @throws IOException if the file cannot be read/parsed","sourceCodeStart":686,"sourceCodeEnd":722,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/ServerConfig.java#L686-L722","documentation":"BSim's ServerConfig parser reads a server config file line by line, tracking recognized keys in a `keyValue` map. Each controlled setting key may be set at most once: when the parser encounters a key whose stored value is already non-empty, it throws IOException(\"Multiple settings for: \" + key). This prevents ambiguous or contradictory configuration values.","triggerScenarios":"Editing a BSim server .conf (e.g. bsimserver.conf) and listing the same controlled directive twice, such as two `database`, `port`, or `repository` lines. The parser reaches the second assignment, sees `curval` is already populated, and throws.","commonSituations":"Hand-merging config snippets; copy-pasting a template block without deleting the original; appending new config during a version upgrade and leaving the old line in place; trailing duplicate from a bad sed/awk edit.","solutions":["Read the trailing key name in the message and locate every occurrence of that directive in the config file.","Delete the duplicate line(s), keeping a single canonical value.","Restart the BSim server process so the parser re-reads the cleaned config.","Add a pre-flight lint (grep for repeated keys) to CI for config files."],"exampleFix":"# before\nport       8080\ndatabase   bsim_primary\nport       9090        # duplicate -- remove\n# after\nport       8080\ndatabase   bsim_primary","handlingStrategy":"validation","validationCode":"// Before handing the file to ServerConfig, scan for duplicate controlled keys.\n// (Adapt 'controlledKeys' to the set BSim recognizes: database, port, etc.)\nSet<String> controlledKeys = Set.of(\"database\", \"port\", \"repository\");\nMap<String, Long> counts = new HashMap<>();\nfor (String line : Files.readAllLines(Path.of(confPath))) {\n    String[] kv = line.trim().split(\"\\\\s+\", 2);\n    if (kv.length == 2 && controlledKeys.contains(kv[0]))\n        counts.merge(kv[0], 1L, Long::sum);\n}\nMap<String, Long> dups = counts.entrySet().stream()\n    .filter(e -> e.getValue() > 1)\n    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));\nif (!dups.isEmpty()) throw new IllegalStateException(\"Duplicate keys: \" + dups);","typeGuard":null,"tryCatchPattern":"try {\n    ServerConfig.parse(confFile);\n} catch (IOException e) {\n    if (e.getMessage().startsWith(\"Multiple settings for:\")) {\n        // surface the duplicated key to the operator; do not retry\n        throw new ConfigException(\"Fix duplicate directive: \" + e.getMessage(), e);\n    }\n    throw e;\n}","preventionTips":["Keep a single canonical config file per BSim server; avoid merge-by-append.","Lint config files in CI for repeated keys before deploy.","Document each recognized key once and remove superseded lines on upgrade."],"tags":["config","bsim","server-config","parse","io"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}