OpenAPITools/openapi-generator · error · IllegalArgumentException

cacheScope requires 'key|content' or 'key\ncontent'

Error message

cacheScope requires 'key|content' or 'key\ncontent'

What it means

CacheLambda is a mustache lambda (registered as 'cache' by AbstractCSharpCodegen for C# generators) that stores a template fragment for later reuse: its body must be 'key|content' or a first-line key followed by content. If the rendered fragment contains neither '|' nor a line break, no separator exists to split key from content and an IllegalArgumentException is thrown at template render time. This is an authoring error in the mustache template, not in the OpenAPI spec.

Source

Thrown at modules/openapi-generator/src/main/java/org/openapitools/codegen/templating/mustache/CacheLambda.java:58

    public CacheLambda(CacheContent cacheContent) {
        this.cacheContent = cacheContent;
    }

    @Override
    public void execute(Fragment fragment, Writer writer) throws IOException {
        String content = fragment.execute();

        // Accept either "key|content" or a multiline form where the first line is the key.
        int separatorIndex = content.indexOf('|');
        if (separatorIndex < 0) {
            int lineBreakIndex = findFirstLineBreakIndex(content);
            if (lineBreakIndex >= 0) {
                separatorIndex = lineBreakIndex;
            }
        }

        if (separatorIndex < 0) {
            throw new IllegalArgumentException("cacheScope requires 'key|content' or 'key\\ncontent'");
        }

        String key = content.substring(0, separatorIndex).trim();
        if (key.isEmpty()) {
            throw new IllegalArgumentException("cacheScope key cannot be empty");
        }

        int contentStartIndex = separatorIndex + 1;
        // For CRLF, skip both '\r' and '\n'. For LF-only/CR-only, skip just one character.
        if (separatorIndex < content.length() && content.charAt(separatorIndex) == '\r') {
            if (contentStartIndex < content.length() && content.charAt(contentStartIndex) == '\n') {
                contentStartIndex++;
            }
        }

        this.cacheContent.contentByKey.put(key, content.substring(contentStartIndex));
    }

View on GitHub (pinned to fcec517be3)

Solutions

  1. Add a separator: write {{#cache}}key|content{{/cache}}, or put the key alone on the first line and the content on following lines.
  2. Verify with a trivial test render (one model) before running full generation so template errors surface quickly.
  3. Check you are using {{#cache}} for storing and {{#recall}}/{{#recallOnce}} for reading — mixing them up produces empty or malformed bodies.

Example fix

{{! before }}
{{#cache}}UserModel{{/cache}}

{{! after }}
{{#cache}}UserModel|public partial class UserModel { }{{/cache}}
Defensive patterns

Strategy: validation

Validate before calling

# crude template lint: every cache block must contain '|' or span multiple lines
grep -rnE '\{\{#cache\}\}[^|}]*\{\{/cache\}\}' templates/ && {
  echo "ERROR: {{#cache}} body needs 'key|content' or a newline after the key" >&2; exit 1;
}

Try / catch

try {
    template.execute(scope, writer);
} catch (IllegalArgumentException e) {
    // template authoring bug: report file + block, not the raw stack
    throw new RuntimeException("cache lambda misuse in template: " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: A custom/modified mustache template (e.g. a C# modelTemplate) containing {{#cache}}UserModel{{/cache}} — the whole body is one line with no '|', so separatorIndex stays -1 and the lambda throws while rendering.

Common situations: Teams editing bundled mustache templates to add caching of repeated blocks; forgetting the pipe convention when copying from {{#recall}} examples; whitespace-stripping template pipelines that collapse the newline of a multiline key/content form.

Related errors


AI-assisted analysis of OpenAPITools/openapi-generator@fcec517be3 (2026-08-22). Data as JSON: /api/errors/a6cf7d3ba0784e29. Report an issue: GitHub.