karatelabs/karate · error · RuntimeException

multipart fields expects a map:

Error message

multipart fields expects a map: 

What it means

The `multipart fields <expr>` step evaluates an expression that must yield a Map of field name to value. If the evaluated result is not a Map, StepExecutor throws this RuntimeException including the step text.

Solutions

  1. Ensure the expression evaluates to a JSON object/map: `multipart fields { field1: 'value1', field2: '#(var)' }`.
  2. Print the value first (`* print myFields`) and confirm it is a map.
  3. If your data is a list, switch to the `multipart files` step.
  4. Fix the variable/expression so it doesn't resolve to null or a scalar.

Example fix

// before
* def fields = [{ name: 'a' }]
And multipart fields fields
// after
* def fields = { a: 'valueA', b: 'valueB' }
And multipart fields fields
Defensive patterns

Strategy: type-guard

Validate before calling

// Guard before the step
* def fields = myFields || {}
* assert typeof fields == 'map'
And multipart fields fields

Type guard

function isNonEmptyMap(v) { return v != null && typeof v === 'object' && !Array.isArray(v); }

Try / catch

try { scenario.run(step) } catch (RuntimeException e) { if (e.getMessage().startsWith("multipart fields expects a map")) { /* eval the expression and verify it's a map */ } throw e; }

Prevention

When it happens

Trigger: `multipart fields` with an expression evaluating to a list, string, or null — e.g. passing a JSON array, a scalar, or a function call returning the wrong shape.

Common situations: Reusing a variable intended for `multipart files` (a list) in `multipart fields`; an eval producing null because a JSON path missed; typos in variable names.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/50bc0f15658bed86. Report an issue: GitHub.

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/core/StepExecutor.java:2519

    @SuppressWarnings("unchecked")
    private void executeMultipartFields(Step step) {
        Object value = evalKarateExpression(step.getText());
        if (value instanceof Map) {
            Map<String, Object> fields = (Map<String, Object>) value;
            for (Map.Entry<String, Object> entry : fields.entrySet()) {
                Map<String, Object> multipartMap = new HashMap<>();
                multipartMap.put("name", entry.getKey());
                Object fieldValue = entry.getValue();
                if (fieldValue instanceof Map) {
                    // V1 behavior: merge map fields (e.g., { value: 'x', contentType: 'y' })
                    multipartMap.putAll((Map<String, Object>) fieldValue);
                } else {
                    multipartMap.put("value", fieldValue);
                }
                http().multiPart(multipartMap);
            }
        } else {
            throw new RuntimeException("multipart fields expects a map: " + step.getText());
        }
    }

    /**
     * Handles: multipart files [{ read: 'file1.txt', name: 'file1' }, { read: 'file2.txt', name: 'file2' }]
     * Also handles V1 map syntax: multipart files { myFile1: {...}, myFile2: {...} }
     * where map keys become the part names.
     */
    @SuppressWarnings("unchecked")
    private void executeMultipartFiles(Step step) {
        Object value = evalKarateExpression(step.getText());
        if (value instanceof List) {
            List<Object> files = (List<Object>) value;
            for (Object item : files) {
                processMultipartFileEntry(item, null);
            }
        } else if (value instanceof Map) {
            // V1 compatibility: map where keys are part names

View on GitHub (pinned to a22eb90246)