kestra-io/kestra · error · PebbleException
The 'secret' function cannot be called with both 'subkey' an
Error message
The 'secret' function cannot be called with both 'subkey' and 'full' arguments.
What it means
The secret() function supports two modes: retrieving a single sub-key from a JSON secret (via 'subkey') or retrieving the full secret object with metadata (via 'full=true'). These modes are mutually exclusive because 'full' returns the entire secret as a structured object while 'subkey' extracts one field. Passing both makes the intent ambiguous and is rejected.
Source
Thrown at core/src/main/java/io/kestra/core/runners/pebble/functions/SecretFunction.java:74
public Object execute(Map<String, Object> args, PebbleTemplate self, EvaluationContext context, int lineNumber) {
String key = getSecretKey(args, self, lineNumber);
String namespace = (String) args.get(NAMESPACE_ARG);
Map<String, String> flow = (Map<String, String>) context.getVariable("flow");
String flowNamespace = flow.get(NAMESPACE_ARG);
String flowTenantId = flow.get("tenantId");
if (namespace == null) {
namespace = flowNamespace;
} else {
namespaceService.get().checkAllowedNamespace(flowTenantId, namespace, flowTenantId, flowNamespace);
}
final String subkey = (String) args.get(SUBKEY_ARG);
final boolean full = Boolean.TRUE.equals(args.get(FULL_ARG));
if (full && subkey != null && !subkey.isEmpty()) {
throw new PebbleException(null, "The 'secret' function cannot be called with both 'subkey' and 'full' arguments.", lineNumber, self.getName());
}
try {
if (full) {
SecretObject secretObject = secretService.get().findSecretObject(flowTenantId, namespace, key);
consumeSecret(context, secretObject.value());
Map<String, Object> result = new LinkedHashMap<>();
result.put(VALUE_KEY, secretObject.value());
if (!secretObject.metadata().isEmpty()) {
secretObject.metadata().values().forEach(value -> consumeSecret(context, value));
result.put(METADATA_KEY, secretObject.metadata());
}
return result;
}
String secret = secretService.get().findSecret(flowTenantId, namespace, key);
View on GitHub (pinned to 823fada927)
Solutions
- Remove the 'subkey' argument when using full=true: {{ secret('MY_KEY', full=true) }}.
- Or remove the 'full' argument when using subkey: {{ secret('MY_KEY', subkey='password') }}.
- If branching logic needs both modes, use an if/else in Pebble to select one path at a time.
Example fix
# before
{{ secret('MY_KEY', subkey='password', full=true) }}
# after — choose one mode
{{ secret('MY_KEY', subkey='password') }}
# or
{{ secret('MY_KEY', full=true).value }} Defensive patterns
Strategy: validation
Validate before calling
# Never pass both subkey and full to secret().
# Use conditional logic to select one mode:
{% if inputs.full_mode %}{{ secret(inputs.key, full=true) }}{% else %}{{ secret(inputs.key, subkey=inputs.subkey) }}{% endif %} Prevention
- Decide upfront whether you need a single sub-key or the full secret object.
- Use if/else branching in Pebble to select one mode at a time.
- Remove stale arguments when refactoring between subkey and full modes.
When it happens
Trigger: Calling {{ secret('MY_KEY', subkey='password', full=true) }}. The 'full' argument resolves to true (either explicitly or via a variable) at the same time subkey is a non-empty string.
Common situations: Gradually migrating from subkey-based access to full-object access and forgetting to remove the old subkey argument. A flow input or variable populating both arguments conditionally. Template reuse where one branch sets subkey and another sets full, and both are active.
Related errors
- The 'secret' function expects an argument 'key'.
- The 'decrypt' function expects two arguments 'key' and 'encr
- The 'render' function expects an argument 'toRender'.
- The 'render' function expects an optional argument 'recursiv
- Cannot find secret sub-key '%s' in secret '%s'.
AI-assisted analysis of kestra-io/kestra@823fada927 (2026-08-14).
Data as JSON: /api/errors/88fc4e01ef1a5c42.
Report an issue: GitHub.