{"record":{"id":"ad01c92598c70237","repo":"MonoGame/MonoGame","slug":"cannot-access-activecontext-because-there-is-no-ac","errorCode":null,"errorMessage":"Cannot access ActiveContext because there is no active context. Make sure that ContextScopeFactory.BeginContext has been called with the `using` keyword","messagePattern":"Cannot access ActiveContext because there is no active context\\. Make sure that ContextScopeFactory\\.BeginContext has been called with the `using` keyword","errorType":"exception","errorClass":"PipelineException","httpStatus":null,"severity":"error","filePath":"MonoGame.Framework.Content.Pipeline/ContextScopeFactory.cs","lineNumber":83,"sourceCode":"        /// If no operations are running (and therefor there is no context), this\n        /// accessor will throw a <see cref=\"PipelineException\"/>.\n        ///\n        /// Use the <see cref=\"HasActiveContext\"/> to check if there is an active context.\n        ///\n        /// <para>\n        /// Each Task-chain may have its own unique ActiveContext, but if a task-chain\n        /// does not have an active context, then the parent task's active context will be used\n        /// recursively. This is the behaviour of AsyncLocal.\n        /// </para>\n        /// </summary>\n        /// <exception cref=\"PipelineException\"></exception>\n        public static IContentContext ActiveContext\n        {\n            get\n            {\n                if (_activeContext.Value == null)\n                {\n                    throw new PipelineException(\n                        $\"Cannot access {nameof(ActiveContext)} because there is no active context. Make sure that {nameof(ContextScopeFactory)}.{nameof(BeginContext)} has been called with the `using` keyword\");\n                }\n\n                return _activeContext.Value;\n            }\n        }\n\n        /// <summary>\n        /// Start a <see cref=\"ContentProcessorContext\"/> operation.\n        /// The <see cref=\"ContentProcessorContext\"/> instance will be adapted into a\n        /// <see cref=\"IContentContext\"/>\n        ///\n        /// </summary>\n        /// <param name=\"context\"></param>\n        /// <returns>\n        /// <b>this return value must be disposed when the context operation is complete!</b>\n        /// </returns>\n        public static IContentContext BeginContext(ContentProcessorContext context)","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/MonoGame/MonoGame/blob/1d71bbd0ff4071a03caa583aa3bc56b85924a819/MonoGame.Framework.Content.Pipeline/ContextScopeFactory.cs#L65-L101","documentation":"Thrown when reading ContextScopeFactory.ActiveContext while no content operation scope is active on the current async-local context stack. The factory uses AsyncLocal<IContentContext> to track the most recent scope; accessing ActiveContext before BeginContext has established (and not yet disposed) a scope violates the scope contract. Callers must wrap the access in a BeginContext using-block.","triggerScenarios":"Accessing ContextScopeFactory.ActiveContext from code that runs outside a 'using var scope = ContextScopeFactory.BeginContext(...)' block; accessing it after the scope was already disposed; accessing it from a different Task-chain whose AsyncLocal value was never set and that has no parent context to inherit.","commonSituations":"Refactoring pipeline code so a helper method is called before BeginContext; running importer/processor logic in a detached Task that lost the AsyncLocal context flow; forgetting the using statement on the scope returned by BeginContext so it disposes immediately.","solutions":["Guard every access with 'if (ContextScopeFactory.HasActiveContext)' or ensure the call site is inside a 'using (ContextScopeFactory.BeginContext(ctx))' block.","Move the ActiveContext access into the body of the using-scope established by BeginContext.","If invoking pipeline work on a separate Task, capture and re-establish the context inside that Task via BeginContext.","Audit dispose ordering: ensure the scope is disposed only after all downstream ActiveContext reads complete."],"exampleFix":"// before\nvar ctx = ContextScopeFactory.ActiveContext; // throws if no scope\n\n// after\nif (ContextScopeFactory.HasActiveContext)\n{\n    var ctx = ContextScopeFactory.ActiveContext;\n    // ...\n}\n// or ensure a scope is active:\nusing var scope = ContextScopeFactory.BeginContext(processorContext);\nvar ctx = ContextScopeFactory.ActiveContext;","handlingStrategy":"validation","validationCode":"// Guard before accessing ActiveContext:\nif (!ContextScopeFactory.HasActiveContext)\n{\n    throw new InvalidOperationException(\n        \"Attempted to access ActiveContext outside a BeginContext scope.\");\n}\nvar ctx = ContextScopeFactory.ActiveContext;","typeGuard":null,"tryCatchPattern":"try\n{\n    var ctx = ContextScopeFactory.ActiveContext;\n    // use ctx\n}\ncatch (PipelineException ex) when (ex.Message.Contains(\"no active context\"))\n{\n    // Re-establish a scope or surface a clear configuration error\n    throw new InvalidOperationException(\"Content operation started without an active context scope.\", ex);\n}","preventionTips":["Always wrap content operations in 'using var scope = ContextScopeFactory.BeginContext(ctx);'.","Never read ActiveContext before BeginContext has been entered or after its scope is disposed.","When offloading to a Task, re-establish the scope inside that Task since AsyncLocal flows but a disposed scope is gone.","Static-analyze for ActiveContext accesses not enclosed in a BeginContext using-block."],"tags":["content-pipeline","context-scope","async-local","monogame"],"backgroundTag":null,"analyzedSha":"1d71bbd0ff4071a03caa583aa3bc56b85924a819","analyzedAt":"2026-08-13T17:10:33.625Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}