{"record":{"id":"050467552cc12f2d","repo":"stanfordnlp/CoreNLP","slug":"attribute-already-defined-attr-image","errorCode":null,"errorMessage":"Attribute already defined: ${attr.image}","messagePattern":"Attribute already defined: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/ling/tokensregex/parser/TokenSequenceParser.java","lineNumber":1919,"sourceCode":"    case STR:{\n      value = RelaxedStringToken();\n      break;\n      }\n    case NONNEGINT:\n    case INT:\n    case REAL:{\n      value = NumberToken();\n      break;\n      }\n    default:\n      jj_la1[65] = jj_gen;\n      jj_consume_token(-1);\n      throw new ParseException();\n    }\nif (value != null) { str = value.image; }\n              if (attr != null && str != null)  {\n                if (attributes.containsKey(attr.image)) {\n                {if (true) throw new Error(\"Attribute already defined: \" + attr.image);}\n                }\n                attributes.put(attr.image, str);\n              }\n          {if (\"\" != null) return attributes;}\n    throw new Error(\"Missing return statement in function\");\n}\n\n  final public Token NumberToken() throws ParseException {Token value = null;\n    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {\n    case NONNEGINT:{\n      value = jj_consume_token(NONNEGINT);\n      break;\n      }\n    case INT:{\n      value = jj_consume_token(INT);\n      break;\n      }\n    case REAL:{","sourceCodeStart":1901,"sourceCodeEnd":1937,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/ling/tokensregex/parser/TokenSequenceParser.java#L1901-L1937","documentation":"Similar to the attribute-match check, this parser production parses simple attribute assignments (no match-value concatenation) and throws 'Attribute already defined: <attr>' when the same attribute key is assigned twice in one attribute block. The map check at line 1919 rejects the second assignment.","triggerScenarios":"Parsing an attribute list such as '{ word:\"foo\" word:\"bar\" }' where an attribute key is set more than once in the same specification.","commonSituations":"Generated or machine-merged TokensRegex rules emitting duplicate attribute assignments; developers duplicating a line when editing rules by hand.","solutions":["Delete the duplicate attribute assignment or keep only the intended value.","If multiple values are needed, use a regex or disjunction in one attribute value.","Lint rule files for duplicate keys before loading them into the annotator.","Fix the generating code if rules are produced programmatically."],"exampleFix":"// before\nString node = \"{ word:\\\"foo\\\" word:\\\"bar\\\" }\";\n// after\nString node = \"{ word:/foo|bar/ }\";","handlingStrategy":"validation","validationCode":"java.util.Set<String> seen = new java.util.HashSet<>();\nfor (String line : attributeLines) {\n  String key = line.split(\":\", 2)[0].trim();\n  if (!seen.add(key)) throw new IllegalStateException(\"Attribute assigned twice: \" + key);\n}","typeGuard":null,"tryCatchPattern":"try {\n  attrs = parser.parseAttributeList(text);\n} catch (Error e) {\n  if (e.getMessage() != null && e.getMessage().startsWith(\"Attribute already defined\")) {\n    throw new IllegalArgumentException(\"Duplicate attribute assignment: \" + e.getMessage(), e);\n  }\n  throw e;\n}","preventionTips":["Keep one assignment per attribute key per node.","Merge duplicate assignments into a single value or disjunction.","If rules are generated, assert uniqueness of keys before emission."],"tags":["parser","tokensregex","duplicate-key","java"],"backgroundTag":"conflicting-config-options","analyzedSha":"1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a","analyzedAt":"2026-09-10T02:24:07.274Z","contentChangedAt":"2026-09-10T02:24:07.274Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}