{"record":{"id":"393658520c844a6f","repo":"dotnet/maui","slug":"xc0128","errorCode":"XC0128","errorMessage":"A key is required in {StaticResource}.","messagePattern":"A key is required in (.+?)\\.","errorType":"exception","errorClass":"BuildException","httpStatus":null,"severity":"error","filePath":"src/Controls/src/Build.Tasks/CompiledMarkupExtensions/StaticResourceExtension.cs","lineNumber":24,"sourceCode":"using Mono.Cecil.Cil;\nusing static Mono.Cecil.Cil.Instruction;\nusing static Mono.Cecil.Cil.OpCodes;\n\nnamespace Microsoft.Maui.Controls.Build.Tasks\n{\n\t//yes, this is a ICompiledMarkupExtension, but declared as ICompiledValueProvider so it's evaluated later (in SetPropertyValue, not CreateObject)\n\tclass StaticResourceExtension : ICompiledValueProvider\n\t{\n\t\tpublic IEnumerable<Instruction> ProvideValue(VariableDefinitionReference vardefref, ModuleDefinition module, BaseNode node, ILContext context)\n\t\t{\n\t\t\tvar name = new XmlName(\"\", \"Key\");\n\t\t\tvar eNode = node as ElementNode;\n\n\t\t\tif (!eNode.Properties.TryGetValue(name, out INode keyNode) && eNode.CollectionItems.Any())\n\t\t\t\tkeyNode = eNode.CollectionItems[0];\n\n\t\t\tif (!(keyNode is ValueNode keyValueNode))\n\t\t\t\tthrow new BuildException(BuildExceptionCode.StaticResourceSyntax, eNode as IXmlLineInfo, null, null);\n\n\t\t\tvar n = eNode;\n\t\t\twhile (n != null)\n\t\t\t{\n\t\t\t\tif (n.Properties.TryGetValue(new XmlName(XamlParser.MauiUri, \"Resources\"), out var resourcesNode))\n\t\t\t\t{\n\t\t\t\t\t//single resource in <Resources>\n\t\t\t\t\tif (resourcesNode is ElementNode irn\n\t\t\t\t\t\t&& irn.Properties.TryGetValue(XmlName.xKey, out INode xKeyNode)\n\t\t\t\t\t\t&& context.Variables.TryGetValue(irn, out VariableDefinition value)\n\t\t\t\t\t\t&& xKeyNode is ValueNode xKeyValueNode\n\t\t\t\t\t\t&& xKeyValueNode.Value as string == keyValueNode.Value as string)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (value.VariableType.FullName == \"System.String\")\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tforeach (var instruction in TryConvert(irn.CollectionItems[0] as ValueNode, eNode, vardefref, module, context))\n\t\t\t\t\t\t\t\tyield return instruction;\n\t\t\t\t\t\t\tyield break;","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/dotnet/maui/blob/f377ff1c5ee04d334d8a925f50c83a6b7afddf03/src/Controls/src/Build.Tasks/CompiledMarkupExtensions/StaticResourceExtension.cs#L6-L42","documentation":"Thrown by the compiled {StaticResource} provider when no Key can be found on the markup node. StaticResource requires a Key attribute (or a single collection item used as the key); if neither is present, keyNode is null or not a ValueNode and the build fails.","triggerScenarios":"Writing <StaticResource /> with no Key attribute and no inline content; binding the Key to a non-literal node (e.g. another markup extension) so keyNode is not a ValueNode; referencing {StaticResource} where the resource key is dynamically computed.","commonSituations":"Forgetting to specify which resource to fetch; confusing StaticResource with DynamicResource syntax; copy-paste leaving an empty {StaticResource}; trying to key on a binding expression which the compiled form cannot evaluate at build time.","solutions":["Add the Key attribute with the resource name: {StaticResource Key=\"MyBrush\"} or the shorthand form.","Ensure the Key is a literal string value, not a nested markup expression.","Confirm the matching resource with that key exists in a reachable ResourceDictionary.","If you need runtime key resolution, switch off XAML compilation for that binding (x:CompileBindings) or use a code-behind lookup."],"exampleFix":"// before\n<ContentPage.Resources>\n  <!-- resource defined -->\n</ContentPage.Resources>\n<Label Text=\"{StaticResource}\" />\n// after\n<Label Text=\"{StaticResource Key=GreetingTemplate}\" />","handlingStrategy":"validation","validationCode":"// Lint: every {StaticResource} must carry a literal Key\nstatic bool StaticResourceHasKey(string expr) {\n    if (!expr.StartsWith(\"{StaticResource\")) return true; // not our concern\n    return expr.Contains(\"Key=\") ||\n           Regex.IsMatch(expr, @\"\\{StaticResource\\s+([A-Za-z_][\\w]*)\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always specify the resource key explicitly in {StaticResource Key=...}.","Keep resource keys in a constants file to avoid mismatches.","Confirm the key exists in a reachable ResourceDictionary before referencing it."],"tags":["xaml","xamlc","staticresource","resource-dictionary","markup-extension","build-time"],"backgroundTag":null,"analyzedSha":"f377ff1c5ee04d334d8a925f50c83a6b7afddf03","analyzedAt":"2026-08-13T14:26:18.069Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}