{"record":{"id":"5e82b367a83aee61","repo":"dotnet/wpf","slug":"sr-parserprovidevaluecantseturi","errorCode":null,"errorMessage":"SR.ParserProvideValueCantSetUri","messagePattern":"SR\\.ParserProvideValueCantSetUri","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/ProvideValueServiceProvider.cs","lineNumber":72,"sourceCode":"        }\n\n        // IProvideValueTarget implementation\n        \n        object IProvideValueTarget.TargetObject\n        {\n            get { return _targetObject; }\n        }\n        object IProvideValueTarget.TargetProperty\n        {\n            get { return _targetProperty; }\n        }\n\n        // IUriContext implementation\n        \n        Uri IUriContext.BaseUri\n        {\n            get { return _context.BaseUri; }\n            set { throw new NotSupportedException(SR.ParserProvideValueCantSetUri); }\n        }\n\n        bool IFreezeFreezables.FreezeFreezables\n        {\n            get\n            {\n                return _context.FreezeFreezables;\n            }\n        }\n\n        bool IFreezeFreezables.TryFreeze(string value, Freezable freezable)\n        {\n            return _context.TryCacheFreezable(value, freezable);\n        }\n\n        Freezable IFreezeFreezables.TryGetFreezable(string value)\n        {\n            return _context.TryGetFreezable(value);","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/ProvideValueServiceProvider.cs#L54-L90","documentation":"When a markup extension's ProvideValue runs, the service provider exposes IUriContext, but its BaseUri setter deliberately throws NotSupportedException: markup extensions must not set the BaseUri during ProvideValue; only the parser owns it. The getter returns the context's BaseUri.","triggerScenarios":"Inside a custom MarkupExtension.ProvideValue implementation, casting IServiceProvider.GetService(typeof(IUriContext)) to IUriContext and assigning to BaseUri, or code that mutates BaseUri while the parser is invoking ProvideValue.","commonSituations":"Custom markup extensions that try to resolve relative URIs by rewriting BaseUri during ProvideValue; code migrated from a static-resource context where BaseUri appeared writable.","solutions":["Do not set BaseUri inside ProvideValue; read it and resolve your URI against it instead","Compute absolute URIs by combining the read-only BaseUri with your relative path","Store desired state in the markup extension's constructor/properties rather than mutating services"],"exampleFix":"// before\nvar uriContext = (IUriContext)serviceProvider.GetService(typeof(IUriContext));\nuriContext.BaseUri = new Uri(\"pack://application:,,,/MyAssembly\");\n// after\nvar uriContext = (IUriContext)serviceProvider.GetService(typeof(IUriContext));\nvar resolved = new Uri(uriContext.BaseUri, relativePath); // read-only, combine instead of assigning","handlingStrategy":"try-catch","validationCode":"var uriCtx = serviceProvider.GetService(typeof(IUriContext)) as IUriContext;\n// never assign uriCtx.BaseUri inside ProvideValue","typeGuard":null,"tryCatchPattern":"try { ProvideValueCore(sp); }\ncatch (NotSupportedException ex) when (ex.Message.Contains(\"BaseUri\")) { /* stop mutating BaseUri; read instead */ }","preventionTips":["Treat services obtained from IServiceProvider as read-only","Resolve relative URIs against BaseUri rather than overwriting it","Never persist mutated service state inside markup extensions"],"tags":["wpf","xaml","not-supported","markup-extension"],"backgroundTag":"unsupported-operation","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}