{"record":{"id":"1cec1e51cbe26237","repo":"GraphiteEditor/Graphite","slug":"value-for-key-k-was-already-given","errorCode":null,"errorMessage":"value for key {k} was already given","messagePattern":"value for key (.+?) was already given","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"proc-macros/src/hint.rs","lineNumber":24,"sourceCode":"fn parse_hint_helper_attrs(attrs: &[Attribute]) -> syn::Result<(Vec<LitStr>, Vec<LitStr>)> {\n\tfold_error_iter(\n\t\tattrs\n\t\t\t.iter()\n\t\t\t.filter(|a| a.path().get_ident().is_some_and(|i| i == \"hint\"))\n\t\t\t.map(|attr| attr.parse_args::<AttrInnerKeyStringMap>()),\n\t)\n\t.and_then(|v: Vec<AttrInnerKeyStringMap>| {\n\t\tfold_error_iter(AttrInnerKeyStringMap::multi_into_iter(v).map(|(k, mut v)| match v.len() {\n\t\t\t0 => panic!(\"internal error: a key without values was somehow inserted into the hashmap\"),\n\t\t\t1 => {\n\t\t\t\tlet single_val = v.pop().unwrap();\n\t\t\t\tOk((LitStr::new(&k.to_string(), Span::call_site()), single_val))\n\t\t\t}\n\t\t\t_ => {\n\t\t\t\t// the first value is ok, the other ones should error\n\t\t\t\tlet after_first = v.into_iter().skip(1);\n\t\t\t\t// this call to fold_error_iter will always return Err with a combined error\n\t\t\t\tfold_error_iter(after_first.map(|lit| Err(syn::Error::new(lit.span(), format!(\"value for key {k} was already given\"))))).map(|_: Vec<()>| unreachable!())\n\t\t\t}\n\t\t}))\n\t})\n\t.map(|v| v.into_iter().unzip())\n}\n\npub fn derive_hint_impl(input_item: TokenStream2) -> syn::Result<TokenStream2> {\n\tlet input = syn::parse2::<DeriveInput>(input_item)?;\n\n\tlet ident = input.ident;\n\n\tmatch input.data {\n\t\tData::Enum(data) => {\n\t\t\tlet variants = data.variants.iter().map(|var: &Variant| two_segment_path(ident.clone(), var.ident.clone())).collect::<Vec<_>>();\n\n\t\t\tlet hint_result = fold_error_iter(data.variants.into_iter().map(|var: Variant| parse_hint_helper_attrs(&var.attrs)));\n\n\t\t\thint_result.map(|hints: Vec<(Vec<LitStr>, Vec<LitStr>)>| {","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/GraphiteEditor/Graphite/blob/c507b356453361e31638b8bff8f6d46b6da2961e/proc-macros/src/hint.rs#L6-L42","documentation":"The `#[hint(key = \"value\")]` helper attribute feeds the `Hint` derive a key→string map (mouse-button tooltips etc.). Keys are collected across every #[hint] attribute on the item into one map, and each key must appear exactly once; the first occurrence wins silently, and every subsequent occurrence raises this compile-time error pointing at the duplicate literal.","triggerScenarios":"Writing the same key twice in one attribute (`#[hint(rmb = \"foo\", rmb = \"bar\")]`), or repeating a key across stacked attributes (`#[hint(a = \"1\")] #[hint(a = \"2\")]`) on the same enum variant or struct. Only the extras after the first are errored.","commonSituations":"Merge conflicts resolved by keeping both sides of a hint list, copy-pasting a hint attribute and editing only the value while forgetting the key, or tooling that concatenates hint attributes.","solutions":["Find the duplicated key named in the error message and delete all but one `key = \"value\"` pair.","If two hints were intentional, rename the second occurrence to a distinct key.","After fixing, run `cargo check` again — only one duplicate is reported per pass, so repeat until clean."],"exampleFix":"// before\n#[derive(Hint)]\nenum Tool {\n\t#[hint(lmb = \"Draw\", lmb = \"Erase\")]\n\tBrush,\n}\n\n// after\n#[derive(Hint)]\nenum Tool {\n\t#[hint(lmb = \"Draw\")]\n\tBrush,\n}","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use each hint key at most once per item, including across stacked #[hint] attributes.","After merge conflicts in hint lists, grep the variant for repeated keys before compiling.","Run `cargo check` after editing hint attributes — the error names the key and spans the duplicate literal."],"tags":["rust","proc-macro","hint","duplicate-keys","attributes"],"backgroundTag":"duplicate-attribute-key","analyzedSha":"c507b356453361e31638b8bff8f6d46b6da2961e","analyzedAt":"2026-08-16T21:57:18.596Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}