karatelabs/karate · error · RuntimeException

multipart files entry must be a map:

Error message

multipart files entry must be a map: 

What it means

Karate's multipart 'files' keyword expects each entry in the files collection to be a Map describing the file to upload (e.g. with 'read', 'name', 'filename', 'contentType' keys). When an entry is not a Map (a bare string, list, number, etc.), StepExecutor cannot convert it into the internal multiPart structure and throws this RuntimeException naming the offending item. It is a fail-fast argument-shape validation inside multipart request construction.

Solutions

  1. Wrap each multipart files entry in a map with at least a 'read' key: { read: '#(path)', name: 'file' }
  2. Log the variable with print before the multipart call to confirm its type
  3. If uploading by path string, construct the map explicitly rather than passing the raw string
  4. Check whether an earlier step overwrote the variable with a scalar value

Example fix

// before
* def myFile = 'upload.png'
* multipart file myFile
// after
* def myFile = { read: 'upload.png', name: 'file' }
* multipart file myFile
Defensive patterns

Strategy: validation

Validate before calling

// karate
* if (!myFile.__proto__ === {}.constructor) karate.fail('multipart files entry must be a map')
// or in JS: karate.match('myFile.#(map)', true)

Prevention

When it happens

Trigger: Using `* multipart file foo` where the variable `foo` holds a plain string path, JSON array, or other non-map value instead of a map like {read: 'file.txt', name: 'file'}; passing an entry of a files list that was built dynamically and ended up as a non-map element.

Common situations: Copying Karate 0.x/1.x string-style multipart syntax (`multipart file myFile = 'path.txt'`) into this engine, which expects map entries; building files entries in JS and forgetting the map wrapper; typos where a variable resolves to the wrong type.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

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

                    } catch (Exception e) {
                        throw new RuntimeException("failed to read file: " + readPath, e);
                    }
                }
            } else if (fileMap.get("value") != null) {
                multipartMap.put("value", fileMap.get("value"));
            }

            // Copy other properties
            if (fileMap.get("filename") != null) {
                multipartMap.put("filename", fileMap.get("filename"));
            }
            if (fileMap.get("contentType") != null) {
                multipartMap.put("contentType", fileMap.get("contentType"));
            }

            http().multiPart(multipartMap);
        } else {
            throw new RuntimeException("multipart files entry must be a map: " + item);
        }
    }

    /**
     * Handles: multipart entity value
     * For sending a single entity as the multipart body (advanced use case)
     */
    @SuppressWarnings("unchecked")
    private void executeMultipartEntity(Step step) {
        String expr = step.getDocString() != null ? step.getDocString() : step.getText();
        Object value = evalKarateExpression(expr);

        if (value instanceof Map) {
            // Single entity map with name, value, etc.
            http().multiPart((Map<String, Object>) value);
        } else {
            // Wrap in a default map
            Map<String, Object> multipartMap = new HashMap<>();

View on GitHub (pinned to a22eb90246)