fix(nixos): accept valid plus-bearing system output paths

Open Beginner friendly
#23 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
78/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
linux, nixos, shell
Domain
devops

Research direction

Read skills/headless/scripts/linux/apply.sh around lines 151–153, where the output path is validated. Compare the accepted pattern with the evaluated plain and plus-bearing NixOS paths in the issue, then check the validation boundary with both names and malformed or unrelated paths. Done means valid plus-bearing NixOS paths pass while malformed paths remain rejected.

Written by the indexing model from the issue text.

Description

Summary

Linux apply.sh validates a NixOS system output path with a narrower character set than Nix permits in a derivation name. A valid custom system.name containing + produces a valid evaluated NixOS output path, but the exact production validation rejects that path as “the build gave no system path.”

Tested source and environment

Headless main at fe1a381c6f382ec3c9822da0e706484414bc63e0. A Crabbox 0.82.0 Ubuntu ARM64 container evaluated the repository's real locked NixOS example configuration with a plain system.name and then the same name containing +.

This was real Nix evaluation, not a fabricated store path. It did not build or activate a NixOS system, and it did not execute a complete remote apply.sh journey. The rejection was established by applying the exact production regular expression to the evaluated system.build.toplevel.outPath values.

Reproduction

From the checkout with a working Nix store, evaluate the example with each system name:

for name in headlessvariant headless+variant; do
  path=$(nix --extra-experimental-features 'nix-command flakes' \
    eval --raw --impure --expr '
      let
        f = builtins.getFlake (toString ./.);
        machine = f.nixosConfigurations.example-aarch64.extendModules {
          modules = [ { system.name = "'"$name"'"; } ];
        };
      in machine.config.system.build.toplevel.outPath
    ')
  if [[ "$path" =~ ^/nix/store/[a-z0-9]{32}-nixos-system-[A-Za-z0-9._-]+$ ]]; then
    echo "$name accepted"
  else
    echo "$name rejected"
  fi
done

Observed results

system.name=headlessvariant
evaluated_outPath=/nix/store/7xvvnmn053mqifq1ab7sn218vp735f4y-nixos-system-headlessvariant-26.11.20261103.1d06008
headless_accepts=true

system.name=headless+variant
evaluated_outPath=/nix/store/42k09fsfvjvhpdslvzrzwkgv09ibggri-nixos-system-headless+variant-26.11.20261103.1d06008
headless_accepts=false

The configurations differed only in system.name. Nix successfully evaluated both output paths.

Expected behavior and cause

The “Your own config” workflow accepts an existing NixOS flake exposing nixosConfigurations.machine. A supported custom system name should not make an otherwise valid Nix output path fail headless's handoff validation.

In the repository's pinned nixpkgs, system.name is a string option, and the top-level derivation name is constructed from that value and the NixOS label. The real evaluation demonstrates that the plus-bearing name is accepted.

skills/headless/scripts/linux/apply.sh:151-153 captures nix build --print-out-paths and then permits only [A-Za-z0-9._-]+ after the nixos-system- prefix. A plus in the valid evaluated name therefore takes the error branch before activation. Validation should retain its requirement for the expected NixOS store output while accepting the valid name characters at this boundary.

Validation and limitations

Test plain and plus-bearing system names through the output-path boundary, and retain rejection of malformed or unrelated paths. A full NixOS build and remote apply would extend the current proof to the activation workflow; those were not performed in this reproduction.

The plain-name control passed the existing validation and supplies a bounded workaround for operators who can choose another system.name. That control establishes naming compatibility rather than a complete system deployment.

Triage assessment

  • Impact level: P2
  • Assessment status: supported
  • Impact basis: The exact output-path check rejects a valid output path generated by the real locked NixOS configuration for a supported custom system name; source control flow would stop the apply handoff at that boundary.
  • Workaround status: available
  • Workaround basis: The otherwise identical plain-name configuration evaluated successfully and passed the same production check; full system deployment was not tested.
Dominant language
Shell
Stars
92
Forks
6
Avg merge
25m
Merged PRs (30d)
5

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from kunchenguid/headless

All issues in kunchenguid/headless

Similar issues

More Shell/Bash issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.