kestra-io/kestra · error · IllegalArgumentException

You cannot set a namespace both as the function argument and

Error message

You cannot set a namespace both as the function argument and inside the URI

What it means

checkedAllowedNamespaceAndReturnNamespace() throws IllegalArgumentException when a namespace:// URI carries an authority (the namespace inside the URI) AND the caller also passes the 'namespace' function argument. Only one source of namespace is allowed. The surrounding catch wraps it into a PebbleException.

Source

Thrown at core/src/main/java/io/kestra/core/runners/pebble/functions/AbstractFileFunction.java:183

    private String checkIfFileFromAllowedNamespaceAndReturnIt(URI path, String tenantId, String fromNamespace) {

        String namespace = extractNamespace(path);
        namespaceService.get().checkAllowedNamespace(tenantId, namespace, tenantId, fromNamespace);
        return namespace;
    }

    private String checkEnabledLocalFileAndReturnNamespace(Map<String, Object> args, Map<String, String> flow) {
        if (!localFilesConfiguration.enableFileFunctions()) {
            throw new SecurityException("The file:// protocol has been disabled inside the Kestra configuration.");
        }

        return (String) Optional.ofNullable(args.get(NAMESPACE)).orElse(flow.get(NAMESPACE));
    }

    private String checkedAllowedNamespaceAndReturnNamespace(Map<String, Object> args, URI nsFileUri, String tenantId, Map<String, String> flow) {
        if (args.get(NAMESPACE) != null && nsFileUri.getAuthority() != null) {
            throw new IllegalArgumentException("You cannot set a namespace both as the function argument and inside the URI");
        }

        // we will transform nsfile URI into a kestra URI so it is handled seamlessly by all functions
        String customNs = Optional.ofNullable((String) args.get(NAMESPACE)).orElse(nsFileUri.getAuthority());
        if (customNs != null) {
            namespaceService.get().checkAllowedNamespace(tenantId, customNs, tenantId, flow.get(NAMESPACE));
        }
        return Optional.ofNullable(customNs).orElse(flow.get(NAMESPACE));
    }

    @VisibleForTesting
    String extractNamespace(URI path) {
        // Extract namespace from the path, it should be of the form: kestra:///{namespace}/{flowId}/executions/{executionId}/tasks/{taskId}/{taskRunId}/{fileName}'
        // To extract the namespace, we must do it step by step as namespace and taskId can contain the words 'executions' and 'tasks'
        String namespace = path.toString().substring(KESTRA_SCHEME.length());
        if (!EXECUTION_FILE.matcher(namespace).matches()) {
            throw new IllegalArgumentException("Unable to read the file '" + path + "' as it is not an execution file");
        }

View on GitHub (pinned to 823fada927)

Solutions

  1. Specify the namespace in exactly one place: either in the URI (namespace://company.team/file) OR via the argument (read('namespace:///file', namespace='company.team')).
  2. Prefer the URI-authority form for readability and drop the namespace argument.
  3. Validate that the two would match, then delete the redundant one.

Example fix

// before
{{ read('namespace://company.team/data.txt', namespace='company.team') }}
// after
{{ read('namespace://company.team/data.txt') }}
Defensive patterns

Strategy: validation

Validate before calling

// Pebble: specify namespace in exactly one place
{{ read('namespace://company.team/data.txt') }}

Prevention

When it happens

Trigger: Calling {{ read('namespace://company.team/data.txt', namespace='company.team') }} — both the URI authority and the argument specify a namespace.

Common situations: Copy-paste from a template that used the argument form onto a URI that already embeds the namespace; defensive over-specification; refactoring between the two forms without removing one.

Related errors


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