abpframework/abp · error · InvalidOperationException

Invalid include file format in {_source.PhysicalPath}. Usage

Error message

Invalid include file format in {_source.PhysicalPath}. Usage example: <%$ include: ErrorPage.js %>

What it means

Thrown by GenerateRazorPage during cshtml template processing when an include directive opens with '<%$ include:' but no matching closing ' %>' delimiter is found. The code scans for include directives to inline referenced files (like ErrorPage.js) into the generated .cshtml content; if the start marker is found but IndexOf for the end marker returns -1, the directive is malformed and cannot be resolved.

Source

Thrown at framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/GenerateRazorPage.cs:209

        private string ProcessFileIncludes()
        {
            var basePath = Path.GetDirectoryName(_source.PhysicalPath);
            var cshtmlContent = File.ReadAllText(_source.PhysicalPath);

            var startMatch = "<%$ include: ";
            var endMatch = " %>";
            var startIndex = 0;
            while (startIndex < cshtmlContent.Length)
            {
                startIndex = cshtmlContent.IndexOf(startMatch, startIndex, StringComparison.Ordinal);
                if (startIndex == -1)
                {
                    break;
                }
                var endIndex = cshtmlContent.IndexOf(endMatch, startIndex, StringComparison.Ordinal);
                if (endIndex == -1)
                {
                    throw new InvalidOperationException($"Invalid include file format in {_source.PhysicalPath}. Usage example: <%$ include: ErrorPage.js %>");
                }
                var includeFileName = cshtmlContent.Substring(startIndex + startMatch.Length, endIndex - (startIndex + startMatch.Length));
                _logger.LogInformation("    Inlining file {0}", includeFileName);
                var includeFileContent = File.ReadAllText(Path.Combine(basePath, includeFileName));
                cshtmlContent = string.Concat(cshtmlContent.Substring(0, startIndex), includeFileContent, cshtmlContent.Substring(endIndex + endMatch.Length));
                startIndex += includeFileContent.Length;
            }
            return cshtmlContent;
        }
    }

    private class RazorPageGeneratorResult
    {
        public string FilePath { get; set; }

        public string GeneratedCode { get; set; }
    }
}

View on GitHub (pinned to 7ed43b1931)

Solutions

  1. Open the template file referenced by _source.PhysicalPath and fix the include directive to use the full format: `<%$ include: FileName.js %>`
  2. Verify all include directives have matching start (`<%$ include:`) and end (` %>`) delimiters
  3. If you do not need the include, remove the entire directive rather than leaving it partially open

Example fix

<!-- before -->
<%$ include: ErrorPage.js

<!-- after -->
<%$ include: ErrorPage.js %>
Defensive patterns

Strategy: validation

Validate before calling

// Check that all include directives in the template are well-formed before processing
var content = File.ReadAllText(templatePath);
var startMatches = Regex.Matches(content, @"<%\$ include:");
foreach (Match start in startMatches)
{
    var endIndex = content.IndexOf(" %>", start.Index, StringComparison.Ordinal);
    if (endIndex == -1)
    {
        Console.Error.WriteLine($"Malformed include directive at position {start.Index} in {templatePath}");
    }
}

Try / catch

try
{
    var result = generator.Generate();
}
catch (InvalidOperationException ex) when (ex.Message.Contains("Invalid include file format"))
{
    logger.LogError("Template has an unclosed include directive. Fix the <%$ include: ... %> syntax.");
}

Prevention

When it happens

Trigger: A .cshtml template file contains '<%$ include: SomeFile.js' without the closing ' %>', or the closing delimiter was accidentally removed during editing. The while-loop finds startIndex != -1 but endIndex == -1.

Common situations: Template customization where an include directive was partially edited, copy-paste errors leaving unclosed directives, or automated tooling that mangled template files. Occurs during `abp generate-razor-page` or similar template generation commands.

Related errors


AI-assisted analysis of abpframework/abp@7ed43b1931 (2026-08-13). Data as JSON: /api/errors/33438742955a3512. Report an issue: GitHub.