OrchardCMS/OrchardCore · error · ArgumentException

Expected a scope of type

Error message

Expected a scope of type {nameof(FilesScriptScope)}

What it means

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.

Solutions

  1. Create and pass a FilesScriptScope with the correct IFileProvider and BasePath.
  2. Obtain the scope from IScriptingManager in a way bound to the Files engine.
  3. In generic code, resolve the correct engine via IScriptingManager.GetScriptEngine and use its matching scope type.

Example fix

// before
engine.Evaluate(someGenericScope, "text('foo.txt')");
// after
var scope = new FilesScriptScope(fileProvider, basePath);
engine.Evaluate(scope, "text('foo.txt')");
Defensive patterns

Strategy: type-guard

Validate before calling

if (scope is not FilesScriptScope) throw new ArgumentException("Files engine requires a FilesScriptScope.");

Type guard

bool IsFilesScope(IScriptingScope scope) => scope is FilesScriptScope;

Try / catch

try { result = engine.Evaluate(scope, script); }
catch (ArgumentException ex) when (ex.ParamName == "scope") { /* construct a FilesScriptScope and retry */ }

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13). Data as JSON: /api/errors/6c1dd45453de955f. Report an issue: GitHub.

Appendix: source

Thrown at src/OrchardCore/OrchardCore.Infrastructure/Scripting/Files/FilesScriptEngine.cs:23

/// <summary>
/// Provides.
/// </summary>
public class FilesScriptEngine : IScriptingEngine
{
    public string Prefix => "file";

    public IScriptingScope CreateScope(IEnumerable<GlobalMethod> methods, IServiceProvider serviceProvider, IFileProvider fileProvider, string basePath)
    {
        return new FilesScriptScope(fileProvider, basePath);
    }

    public object Evaluate(IScriptingScope scope, string script)
    {
        ArgumentNullException.ThrowIfNull(scope);

        if (scope is not FilesScriptScope fileScope)
        {
            throw new ArgumentException($"Expected a scope of type {nameof(FilesScriptScope)}", nameof(scope));
        }

        if (script.StartsWith("text('", StringComparison.Ordinal) && script.EndsWith("')", StringComparison.Ordinal))
        {
            var filePath = script[6..^2];
            var fileInfo = fileScope.FileProvider.GetRelativeFileInfo(fileScope.BasePath, filePath);
            if (!fileInfo.Exists)
            {
                throw new FileNotFoundException(filePath);
            }

            using var fileStream = fileInfo.CreateReadStream();
            using var streamReader = new StreamReader(fileStream);
            return streamReader.ReadToEnd();
        }
        else if (script.StartsWith("base64('", StringComparison.Ordinal) && script.EndsWith("')", StringComparison.Ordinal))
        {
            var filePath = script[8..^2];

View on GitHub (pinned to 4306c0717f)