kestra-io/kestra · error · ConstraintViolationException

Illegal {type} path:{e.getMessage()}

Error message

Illegal {type} path:{e.getMessage()}

What it means

The `YamlParser.parse(File, Class)` method reads a file's contents via `IOUtils.toString(file.toURI())`. If an `IOException` occurs (file not found, permission denied, unreadable, invalid path), it is caught and re-thrown as a `ConstraintViolationException` with the message 'Illegal {type} path:{detail}'. The `{type}` is the lowercased simple class name (e.g. 'flow', 'template').

Source

Thrown at core/src/main/java/io/kestra/core/serializers/YamlParser.java:69

            if (e.getCause() instanceof JsonProcessingException jsonProcessingException) {
                throw toConstraintViolationException(input, type(cls), jsonProcessingException);
            }

            throw e;
        }
    }

    private static <T> String type(Class<T> cls) {
        return cls.getSimpleName().toLowerCase();
    }

    public static <T> T parse(File file, Class<T> cls) throws ConstraintViolationException {
        try {
            String input = IOUtils.toString(file.toURI(), StandardCharsets.UTF_8);
            return read(input, cls, type(cls));

        } catch (IOException e) {
            throw new ConstraintViolationException(
                "Illegal " + type(cls) + " path:" + e.getMessage(),
                Collections.singleton(
                    ManualConstraintViolation.of(
                        e.getMessage(),
                        file,
                        File.class,
                        type(cls),
                        file.getAbsolutePath()
                    )
                )
            );
        }
    }

    private static <T> T read(String input, Class<T> objectClass, String resource) {
        try {
            return STRICT_MAPPER.readValue(input, objectClass);
        } catch (JsonProcessingException e) {

View on GitHub (pinned to 823fada927)

Solutions

  1. Verify the file exists at the given absolute path before calling parse.
  2. Check file read permissions for the running process.
  3. Use an absolute path rather than a relative one to avoid working-directory ambiguity.
  4. If loading from resources, ensure the resource is packaged correctly (e.g., in the JAR).

Example fix

// before
Flow flow = YamlParser.parse(new File("flows/myflow.yml"), Flow.class);
// after
File file = new File("flows/myflow.yml");
if (!file.exists() || !file.canRead()) {
    throw new IllegalStateException("Cannot read flow file: " + file.getAbsolutePath());
}
Flow flow = YamlParser.parse(file, Flow.class);
Defensive patterns

Strategy: validation

Validate before calling

// Validate file exists and is readable before parsing
import java.io.File;

public static void validateYamlFile(File file) {
    Objects.requireNonNull(file, "file cannot be null");
    if (!file.exists()) {
        throw new IllegalArgumentException("File does not exist: " + file.getAbsolutePath());
    }
    if (!file.isFile()) {
        throw new IllegalArgumentException("Path is not a file: " + file.getAbsolutePath());
    }
    if (!file.canRead()) {
        throw new IllegalArgumentException("Cannot read file: " + file.getAbsolutePath());
    }
}

Type guard

import { existsSync, statSync, constants } from 'fs';

function isReadableFile(path: string): boolean {
    try {
        const stat = statSync(path);
        return stat.isFile();
    } catch {
        return false;
    }
}

Try / catch

try {
    Flow flow = YamlParser.parse(file, Flow.class);
} catch (ConstraintViolationException e) {
    if (e.getMessage().startsWith("Illegal flow path:") || e.getMessage().startsWith("Illegal template path:")) {
        log.error("Could not read YAML file {}: {}", file.getAbsolutePath(), e.getMessage());
        // handle missing/unreadable file
    } else {
        throw e; // re-throw YAML content errors
    }
}

Prevention

When it happens

Trigger: Calling `YamlParser.parse(file, Flow.class)` on a file path that does not exist. The file exists but the process lacks read permissions. The path is a directory, not a file. The URI is malformed.

Common situations: A plugin or test loads a flow YAML from a relative path that resolves incorrectly. A file was deleted between listing and parsing. A CI environment mounts files with restricted permissions.

Related errors


AI-assisted analysis of kestra-io/kestra@823fada927 (2026-08-14). Data as JSON: /api/errors/bdb76037f6e3726a. Report an issue: GitHub.