π Issue
deployChecks fails on shell scripts in boot.initrd.extraFiles with valid sh syntax (=, >, 2>, |) or even echo.
Overview
When using deploy-rs v1.0 with nix 2.28.3, deployChecks fails if a shell script in boot.initrd.extraFiles includes common valid shell syntax like:
Even though nixos-rebuild succeeds and the system works correctly at runtime.
Minimal Reproduction
Directory structure:
.
βββ flake.nix
βββ flake.lock
βββ unlock.sh
flake.nix:
{
description = "Deploy bug with shell script in extraFiles";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
deploy-rs.url = "github:serokell/deploy-rs";
};
outputs = { self, nixpkgs, deploy-rs, ... }:
let
system = "x86_64-linux";
in {
nixosConfigurations.test = nixpkgs.lib.nixosSystem {
inherit system;
modules = [{
system.stateVersion = "25.05";
boot.initrd.extraFiles."/unlock.sh" = ./unlock.sh;
# Required dummy options
fileSystems."/".device = "/dev/null";
# Disable bootloader entirely for evaluation
boot.loader.grub.enable = false;
boot.loader.systemd-boot.enable = false;
boot.loader.generic-extlinux-compatible.enable = false;
}];
};
checks = builtins.mapAttrs
(system: deployLib: deployLib.deployChecks self.deploy)
deploy-rs.lib;
deploy.test = {
hostname = "my-host";
sshUser = "root";
profiles.system.path = self.nixosConfigurations.test.config.system.build.toplevel;
};
};
}
unlock.sh:
#!/bin/sh
echo "Remote unlock initrd shell"
Each of these causes failure independently:
foo=bar
echo hi > /tmp/file
somecmd 2> /dev/null
cmd1 | cmd2
Steps to Reproduce
Fails with:
error: undefined variable 'echo'
at /nix/store/vi24zyx5bvl9baxac3x5z2b7273hxdqi-source/unlock.sh:2:1:
1| #!/bin/sh
2| echo "example script here"
| ^
3|
Environment
- deploy-rs: 1.0
- nix: 2.28.3
- nixos: 25.04 / 25.05
- system: x86_64-linux
Why This Matters
Shell scripts in boot.initrd.extraFiles are copied verbatim to the initrd and should never be parsed as Nix. This bug blocks valid remote-unlock workflows (e.g. over SSH).
β
Suggested Fix
- Treat extraFiles contents as opaque
- Donβt evaluate or parse their syntax
- Optionally allow opt-out from parsing via __noDeployCheck = true or similar
π€ ChatGPT assistance note
I worked with ChatGPT to debug this issue. It helped me:
- Identify that
deployChecks was failing due to boot.initrd.extraFiles including valid shell syntax like =, >, 2>, and |
- Confirm that the files were being misinterpreted by the Nix expression parser even though they were valid for the initrd
- Reproduce the issue using a minimal
flake.nix and unlock.sh example
- Suggest a possible PR direction: skip or bypass parsing for
boot.initrd.extraFiles during schema checks
- Draft the issue template and Markdown body for submission
This saved time narrowing down and presenting the issue clearly.
π Issue
deployChecksfails on shell scripts inboot.initrd.extraFileswith validshsyntax (=,>,2>,|) or evenecho.Overview
When using
deploy-rsv1.0 withnix2.28.3,deployChecksfails if a shell script inboot.initrd.extraFilesincludes common valid shell syntax like:=>2>|echoEven though
nixos-rebuildsucceeds and the system works correctly at runtime.Minimal Reproduction
Directory structure:
.
βββ flake.nix
βββ flake.lock
βββ unlock.sh
flake.nix:unlock.sh:
Each of these causes failure independently:
foo=barecho hi > /tmp/filesomecmd 2> /dev/nullcmd1 | cmd2Steps to Reproduce
Fails with:
Environment
Why This Matters
Shell scripts in boot.initrd.extraFiles are copied verbatim to the initrd and should never be parsed as Nix. This bug blocks valid remote-unlock workflows (e.g. over SSH).
β Suggested Fix
π€ ChatGPT assistance note
I worked with ChatGPT to debug this issue. It helped me:
deployCheckswas failing due toboot.initrd.extraFilesincluding valid shell syntax like=,>,2>, and|flake.nixandunlock.shexampleboot.initrd.extraFilesduring schema checksThis saved time narrowing down and presenting the issue clearly.