apache/seatunnel · error · IllegalArgumentException

input.paths must not be empty

Error message

input.paths must not be empty (input id=${id}).

What it means

A file-collect input must declare at least one path to watch/collect. FileCollectConfig's constructor throws this IllegalArgumentException when `input.paths` (FileCollectOptions.PATHS) is null or an empty list, including the input's id in the message to identify the offending input block.

Solutions

  1. Add at least one path to `input.paths` for the input with the reported id
  2. Use the exact key `paths` (a list), not `path`
  3. Verify glob/variable substitution produces non-empty lists at render time
  4. Remove unused empty input blocks entirely

Example fix

// before
input {
  id = "app-logs"
}
// after
input {
  id = "app-logs"
  paths = ["/var/log/app/*.log"]
}
Defensive patterns

Strategy: validation

Validate before calling

List<String> paths = config.get(FileCollectOptions.PATHS);
if (paths == null || paths.isEmpty()) {
    throw new IllegalArgumentException("input.paths must list at least one path");
}

Type guard

boolean hasPaths(ReadonlyConfig c) {
    List<String> p = c.get(FileCollectOptions.PATHS);
    return p != null && !p.isEmpty();
}

Try / catch

try {
    FileCollectConfig cfg = new FileCollectConfig(config);
} catch (IllegalArgumentException e) {
    log.error("Invalid input config: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Building FileCollectConfig from a ReadonlyConfig whose `input.paths` option is absent or resolves to an empty list; happens per input during agent connector configuration setup.

Common situations: Input block defined with only an id but no paths, YAML/HOCON list rendered empty by variable substitution, or misnaming the key (`path` instead of `paths`) so the list is not found.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/2722368171686e4c. Report an issue: GitHub.

Appendix: source

Thrown at seatunnel-edge-agent/seatunnel-edge-agent-connector/src/main/java/org/apache/seatunnel/edge/agent/connector/config/FileCollectConfig.java:61

    private final String multilineMatch;
    private final boolean multilineNegate;
    private final int multilineMaxLines;
    private final long multilineFlushIdleTimeoutMs;
    private final String outputType;
    private final Charset charset;
    private final String onError;
    private final long globScanIntervalMs;
    private final long closeInactiveMs;

    public FileCollectConfig(ReadonlyConfig config) {
        Objects.requireNonNull(config, "config");
        this.id = config.get(FileCollectOptions.ID);
        if (this.id == null || this.id.trim().isEmpty()) {
            throw new IllegalArgumentException("input.id must be non-empty.");
        }
        List<String> pathList = config.get(FileCollectOptions.PATHS);
        if (pathList == null || pathList.isEmpty()) {
            throw new IllegalArgumentException(
                    "input.paths must not be empty (input id=" + this.id + ").");
        }
        for (String path : pathList) {
            if (path == null || path.trim().isEmpty()) {
                throw new IllegalArgumentException(
                        "input.paths must not contain blank entries (input id=" + this.id + ").");
            }
        }
        this.paths = Collections.unmodifiableList(new ArrayList<>(pathList));
        this.encoding = config.get(FileCollectOptions.ENCODING);
        this.charset = resolveCharset(this.encoding, this.id);
        this.readFromBeginning = config.get(FileCollectOptions.READ_FROM_BEGINNING);
        this.multilinePattern =
                config.getOptional(FileCollectOptions.MULTILINE_PATTERN).orElse(null);
        this.multilineMatch = config.get(FileCollectOptions.MULTILINE_MATCH);
        validateMultilineMatch(this.multilineMatch);
        this.multilineNegate = config.get(FileCollectOptions.MULTILINE_NEGATE);
        this.multilineMaxLines = config.get(FileCollectOptions.MULTILINE_MAX_LINES);

View on GitHub (pinned to cf67b549a7)