<@ULVA73B9P> Is it possible to apply the Jinja `de...
# ask-marvin
u
@Marvin Is it possible to apply the Jinja
default
filter to environment variable references in
prefect.yaml
?
Copy code
schedules:
        active: "{{ $ACTIVE | default(false) }}"
m
thought for 110.9 seconds
Short answer: no. Prefect’s
prefect.yaml
templating is not full Jinja — it’s a lightweight placeholder system. Filters like
default
are not parsed, so
{{ $ACTIVE | default(false) }}
won’t work. What you can do instead: - Use a plain env var placeholder and set it before deploy: - YAML (unquoted so YAML can parse booleans):
Copy code
schedules:
      - interval: 600
        active: {{ $ACTIVE }}
- Shell (ensure lowercase true/false):
Copy code
export ACTIVE=true
    prefect deploy
- If you need a default at the shell level:
Copy code
ACTIVE="${ACTIVE:-false}" prefect deploy
- Use a Prefect Variable and set its value in the UI/API:
Copy code
schedules:
    - interval: 600
      active: "{{ prefect.variables.schedule_active }}"
- Maintain separate schedule definitions (dev/prod) via YAML anchors and pick the one you need per deployment. Notes: - If
$ACTIVE
is unset, the placeholder remains and will likely cause a YAML parse error. Always set it or use one of the alternatives above. - Keep
active
unquoted if you want a real boolean; quoted values become strings.
u
@Marvin Couldn't this be replaced with the
run_shell_script
action?
m
thought for 99.7 seconds
Yes—with a couple of caveats. You can use
prefect.deployments.steps.run_shell_script
to compute a value (e.g., resolve a default) and then reference that step’s output in your
prefect.yaml
. You cannot “set” an env var for later
{{ $VAR }}
placeholders, but you can reference the step’s output instead. Key points: - Put the shell step in
build
(or
push
) so it runs at deploy time.
pull
runs on the worker at flow-run time and cannot influence deployment fields like schedules. - Make the script output exactly
true
or
false
with no newline, and keep
active
unquoted so YAML parses a real boolean. - Reference the step output via its
id
(e.g.,
{{ resolve-active.stdout }}
). Example:
Copy code
build:
  - prefect.deployments.steps.run_shell_script:
      id: resolve-active
      script: 'printf %s "${ACTIVE:-false}"'
      expand_env_vars: true
      stream_output: false

deployments:
  - name: my-deployment
    entrypoint: path/to/flow.py:flow
    schedules:
      - interval: 600
        active: {{ resolve-active.stdout }}
Notes: - This doesn’t enable Jinja filters; it sidesteps them by injecting the computed value. -
run_shell_script
can’t mutate the parent process environment, so don’t expect
{{ $ACTIVE }}
to start working later—use
{{ resolve-active.stdout }}
instead.
u
@Marvin raises error then its line has skipped.
Copy code
Unable to read the specified config file. Reason: while constructing a mapping
  in "deployments/prefect.stg.yaml", line 58, column 17
found unhashable key
  in "deployments/prefect.stg.yaml", line 58, column 18. Skipping.
m
thought for 206.8 seconds
That error means the YAML parser saw a template expression on the left side of a colon (i.e., as a mapping key) without quotes. Unquoted placeholders like {{ ... }} are not valid YAML keys and trigger “found unhashable key.” How to fix: - Always quote any placeholder used as a key. - Placeholders on the right side (as values) can be quoted to be safe as well. Examples:
Copy code
# ✅ Correct: quote placeholders used as keys
work_pool:
  job_variables:
    "{{ some-step.key }}": "{{ some-step.value }}"

# ❌ Incorrect: unquoted placeholder as a key (causes your error)
work_pool:
  job_variables:
    {{ some-step.key }}: "{{ some-step.value }}"
For your schedules.active case using run_shell_script output, do either:
Copy code
# Safe quoting (Prefect will coerce "true"/"false" to a boolean)
schedules:
  - interval: 600
    active: "{{ resolve-active.stdout }}"
or, if you really want to keep it unquoted as a plain boolean, ensure you’re not in a key position and your YAML still parses:
Copy code
# Only do this if your file parses successfully; otherwise quote it
schedules:
  - interval: 600
    active: {{ resolve-active.stdout }}
If you’re still seeing the error, could you paste the snippet around line 58 (a few lines before/after)? That’ll let me point to the exact key that needs quoting.