karatelabs/karate

karate.set(callSingle()) + disk cache wipes config-level Java.type() variables

Open

#2,933 opened on Jun 19, 2026

View on GitHub
 (2 comments) (0 reactions) (0 assignees)Java (1,893 forks)batch import
bughelp wanted

Repository metrics

Stars
 (7,600 stars)
PR merge metrics
 (Avg merge 14h 17m) (25 merged PRs in 30d)

Description

Description

When karate.set(karate.callSingle('feature')) is used to bulk-set variables into scope, and the callSingle result is served from disk cache (subsequent JVM runs), all config-level Java.type() references (from karate-config.js) are wiped from scope.

The first run (cold, no disk cache) works correctly. Any subsequent run within the callSingleCache TTL fails.

Note: I think any Java.type() reference set in karate-config.js will exhibit this issue — RandomUtils is just the example that triggers visibly for us because the feature file calls a method on it.

Steps to Reproduce

Pre-req- Add a Java Type util and callSingleCache TTL in config.

config.rndUtils = Java.type('commonutilhelpers.RandomUtils')
karate.configure('callSingleCache', { minutes: 5 });
  1. Create the below JAVA util being referred to in the config.
package commonutilhelpers;
import java.util.Random;

public class RandomUtils {
    public static String alphaNumString(Integer length) {
        String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
        StringBuilder str = new StringBuilder();
        Random rnd = new Random();
        while (str.length() < length) {
            int index = (int) (rnd.nextFloat() * chars.length());
            str.append(chars.charAt(index));
        }
        return str.toString();
    }
}
  1. Create a feature file using the snippets below.
Feature: karate.set(callSingle()) + disk cache wipes config-level Java.type()

  Background:
    * karate.set( karate.callSingle('classpath:v2MigrationBugs/callSingleDiskCacheWipe/constants.feature') )

    # This uses rndUtils from karate-config.js (Java.type('commonutilhelpers.RandomUtils'))
    # First run (fresh callSingle): works
    # Second run (disk cache): throws "rndUtils.alphaNumString is not a function"
    * def generatedEmail = rndUtils.alphaNumString(8) + '@test.com'
    * karate.logger.debug('generatedEmail =', generatedEmail)

  Scenario: Verify config-level Java.type() survives karate.set(callSingle())
    * match generatedEmail == '#string'
    * assert generatedEmail.endsWith('@test.com')
  1. Create a feature file using the snippets below for constants.feature being called in the above feature.
@ignore
Feature: Simulated Pre-reqs (callSingle target — returns object for karate.set)

  Scenario:
    * def serviceName = 'TestService'
    * def baseUrl = 'https://httpbin.org'
    * def domainPath = '/anything'
    * def someFlag = true
    * def headers = { 'Content-Type': 'application/json' }

To Reproduce-

Perform the mvn clean first. Run the feature file. It passes. Run the feature file again within the TTL limit. It fails.

Expected Behavior

  1. On every run (cold or warm cache), config-level utilities like rndUtils remain available and functional and test should pass.

1st execution report(v1)-

1st execution report(v2)-

Actual Behavior

  1. First run (no disk cache): callSingle executes fresh. karate.set() works correctly. Config variables preserved. Tests pass.
  2. Second run (disk cache hit): Test fails with error.
js failed:
==========
  Code: rndUtils.alphaNumString(8) + '@test.com'
  Error: TypeError: rndUtils.alphaNumString is not a function
==========

1st execution report-

2nd execution report-

Karate Version

2.1.0

Java Version

25.0.2

Operating System

macOS

Contributor guide