{"record":{"id":"6c1dd45453de955f","repo":"OrchardCMS/OrchardCore","slug":"expected-a-scope-of-type-nameof-filesscriptscope","errorCode":null,"errorMessage":"Expected a scope of type {nameof(FilesScriptScope)}","messagePattern":"Expected a scope of type (.+?)","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/OrchardCore/OrchardCore.Infrastructure/Scripting/Files/FilesScriptEngine.cs","lineNumber":23,"sourceCode":"/// <summary>\n/// Provides.\n/// </summary>\npublic class FilesScriptEngine : IScriptingEngine\n{\n    public string Prefix => \"file\";\n\n    public IScriptingScope CreateScope(IEnumerable<GlobalMethod> methods, IServiceProvider serviceProvider, IFileProvider fileProvider, string basePath)\n    {\n        return new FilesScriptScope(fileProvider, basePath);\n    }\n\n    public object Evaluate(IScriptingScope scope, string script)\n    {\n        ArgumentNullException.ThrowIfNull(scope);\n\n        if (scope is not FilesScriptScope fileScope)\n        {\n            throw new ArgumentException($\"Expected a scope of type {nameof(FilesScriptScope)}\", nameof(scope));\n        }\n\n        if (script.StartsWith(\"text('\", StringComparison.Ordinal) && script.EndsWith(\"')\", StringComparison.Ordinal))\n        {\n            var filePath = script[6..^2];\n            var fileInfo = fileScope.FileProvider.GetRelativeFileInfo(fileScope.BasePath, filePath);\n            if (!fileInfo.Exists)\n            {\n                throw new FileNotFoundException(filePath);\n            }\n\n            using var fileStream = fileInfo.CreateReadStream();\n            using var streamReader = new StreamReader(fileStream);\n            return streamReader.ReadToEnd();\n        }\n        else if (script.StartsWith(\"base64('\", StringComparison.Ordinal) && script.EndsWith(\"')\", StringComparison.Ordinal))\n        {\n            var filePath = script[8..^2];","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/OrchardCMS/OrchardCore/blob/4306c0717fe573f6fca1b4955909ddab6a192807/src/OrchardCore/OrchardCore.Infrastructure/Scripting/Files/FilesScriptEngine.cs#L5-L41","documentation":"FilesScriptEngine.Evaluate requires the supplied IScriptingScope to be a FilesScriptScope, which carries the FileProvider and BasePath needed to resolve file references in scripts. Passing any other scope type throws ArgumentException naming the expected type.","triggerScenarios":"Invoking Evaluate (directly or via the Files script engine's methods like text()/base64()) with a scope created for a different engine (e.g. a JS or Liquid scripting scope).","commonSituations":"Mixing script engines: registering custom code that passes a generic or unrelated scope; calling the engine from tests with a plain scope; engine/scope mismatch after refactoring.","solutions":["Create and pass a FilesScriptScope with the correct IFileProvider and BasePath.","Obtain the scope from IScriptingManager in a way bound to the Files engine.","In generic code, resolve the correct engine via IScriptingManager.GetScriptEngine and use its matching scope type."],"exampleFix":"// before\nengine.Evaluate(someGenericScope, \"text('foo.txt')\");\n// after\nvar scope = new FilesScriptScope(fileProvider, basePath);\nengine.Evaluate(scope, \"text('foo.txt')\");","handlingStrategy":"type-guard","validationCode":"if (scope is not FilesScriptScope) throw new ArgumentException(\"Files engine requires a FilesScriptScope.\");","typeGuard":"bool IsFilesScope(IScriptingScope scope) => scope is FilesScriptScope;","tryCatchPattern":"try { result = engine.Evaluate(scope, script); }\ncatch (ArgumentException ex) when (ex.ParamName == \"scope\") { /* construct a FilesScriptScope and retry */ }","preventionTips":["Pair each engine with its matching scope type","Acquire scopes from IScriptingManager rather than hand-building them","Add an assertion in helper code that wraps Evaluate"],"tags":["scripting","type-mismatch","invalid-argument-value"],"backgroundTag":"invalid-argument-value","analyzedSha":"4306c0717fe573f6fca1b4955909ddab6a192807","analyzedAt":"2026-09-13T17:41:05.024Z","contentChangedAt":"2026-09-13T17:41:05.024Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}