Nix flake: desktop package fails to build - missing outputHashes for specta git dependency #8303

Open
opened 2026-02-16 18:09:38 -05:00 by yindo · 5 comments
Owner

Originally created by @jerome-benoit on GitHub (Feb 2, 2026).

Originally assigned to: @rekram1-node on GitHub.

Description

Building opencode-desktop via the Nix flake fails because specta-2.0.0-rc.22 is a git dependency without a corresponding outputHashes entry.

error: No hash was found while vendoring the git dependency specta-2.0.0-rc.22.

Root cause: 04aef44 added tauri-specta which depends on specta via git.

Why CI didn't catch it: a92b792 disabled the nix-desktop workflow without explanation.

Fix options:

  1. Add outputHashes to nix/desktop.nix:
cargoLock = {
  lockFile = ../packages/desktop/src-tauri/Cargo.lock;
  outputHashes = {
    "specta-2.0.0-rc.22" = "sha256-...";
  };
};
  1. Or use a crates.io release instead of git dependency (avoids manual hash maintenance).

  2. Re-enable nix-desktop.yml workflow to catch future regressions.

OpenCode version

1.1.48

Steps to reproduce

nix build github:anomalyco/opencode#desktop

Operating System

Linux x86_64

Originally created by @jerome-benoit on GitHub (Feb 2, 2026). Originally assigned to: @rekram1-node on GitHub. ### Description Building `opencode-desktop` via the Nix flake fails because `specta-2.0.0-rc.22` is a git dependency without a corresponding `outputHashes` entry. ``` error: No hash was found while vendoring the git dependency specta-2.0.0-rc.22. ``` **Root cause:** [04aef44](https://github.com/anomalyco/opencode/commit/04aef44fc30d599f11ea2ada60ed63c4856a18ff) added `tauri-specta` which depends on `specta` via git. **Why CI didn't catch it:** [a92b792](https://github.com/anomalyco/opencode/commit/a92b7923c2baff2d0e6fd59e5ad4cd22790553ae) disabled the `nix-desktop` workflow without explanation. **Fix options:** 1. Add `outputHashes` to `nix/desktop.nix`: ```nix cargoLock = { lockFile = ../packages/desktop/src-tauri/Cargo.lock; outputHashes = { "specta-2.0.0-rc.22" = "sha256-..."; }; }; ``` 2. Or use a crates.io release instead of git dependency (avoids manual hash maintenance). 3. Re-enable `nix-desktop.yml` workflow to catch future regressions. ### OpenCode version 1.1.48 ### Steps to reproduce ```sh nix build github:anomalyco/opencode#desktop ``` ### Operating System Linux x86_64
yindo added the nix label 2026-02-16 18:09:38 -05:00
Author
Owner

@ndrwstn commented on GitHub (Feb 4, 2026):

I realize this may be obvious, but disabling the desktop from the flake is a less-than-ideal solution, and if/when nixpkgs catches up we're going to be breaking a lot of people's flakes who don't expect things to be just disabled?

@ndrwstn commented on GitHub (Feb 4, 2026): I realize this may be obvious, but disabling the desktop from the flake is a less-than-ideal solution, and if/when nixpkgs catches up we're going to be breaking a lot of people's flakes who don't expect things to be just disabled?
Author
Owner

@farefray commented on GitHub (Feb 4, 2026):

jfyi: Was able to bypass with flake hashes:

➜  nixos cat flake.nix
{
  description = "NixOS WSL Configuration";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
    nixos-wsl.url = "github:nix-community/NixOS-WSL";
    nixos-wsl.inputs.nixpkgs.follows = "nixpkgs";
    home-manager.url = "github:nix-community/home-manager";
    home-manager.inputs.nixpkgs.follows = "nixpkgs";
    opencode.url = "github:anomalyco/opencode";
  };

  outputs = { self, nixpkgs, ... }@inputs:
  let
    system = "x86_64-linux";
    # We need a reference to pkgs to use the Rust tools
    pkgs = nixpkgs.legacyPackages.${system};

    # The Fix: we re-vendor the dependencies from scratch, ignoring the broken original
    opencode-patched = inputs.opencode.packages.${system}.desktop.overrideAttrs (old: {
      cargoDeps = pkgs.rustPlatform.importCargoLock {
        lockFile = inputs.opencode + "/packages/desktop/src-tauri/Cargo.lock";
        outputHashes = {
          "specta-2.0.0-rc.22" = "sha256-J+rDfV5Wx82VNbpLRh3g/4LerjKQodgMq7A9S9WGhXU=";
          "tauri-2.9.5" = "sha256-dv5E/+A49ZBvnUQUkCGGJ21iHrVvrhHKNcpUctivJ8M=";
          "tauri-specta-2.0.0-rc.21" = "sha256-n2VJ+B1nVrh6zQoZyfMoctqP+Csh7eVHRXwUQuiQjaQ=";
        };
      };
    });
  in {
    nixosConfigurations.nixos = nixpkgs.lib.nixosSystem {
      inherit system;
      specialArgs = { inherit inputs; opencode-desktop = opencode-patched; };
      modules = [
        ./configuration.nix
      ];
    };
  };
}

@farefray commented on GitHub (Feb 4, 2026): jfyi: Was able to bypass with flake hashes: ``` ➜ nixos cat flake.nix { description = "NixOS WSL Configuration"; inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; nixos-wsl.url = "github:nix-community/NixOS-WSL"; nixos-wsl.inputs.nixpkgs.follows = "nixpkgs"; home-manager.url = "github:nix-community/home-manager"; home-manager.inputs.nixpkgs.follows = "nixpkgs"; opencode.url = "github:anomalyco/opencode"; }; outputs = { self, nixpkgs, ... }@inputs: let system = "x86_64-linux"; # We need a reference to pkgs to use the Rust tools pkgs = nixpkgs.legacyPackages.${system}; # The Fix: we re-vendor the dependencies from scratch, ignoring the broken original opencode-patched = inputs.opencode.packages.${system}.desktop.overrideAttrs (old: { cargoDeps = pkgs.rustPlatform.importCargoLock { lockFile = inputs.opencode + "/packages/desktop/src-tauri/Cargo.lock"; outputHashes = { "specta-2.0.0-rc.22" = "sha256-J+rDfV5Wx82VNbpLRh3g/4LerjKQodgMq7A9S9WGhXU="; "tauri-2.9.5" = "sha256-dv5E/+A49ZBvnUQUkCGGJ21iHrVvrhHKNcpUctivJ8M="; "tauri-specta-2.0.0-rc.21" = "sha256-n2VJ+B1nVrh6zQoZyfMoctqP+Csh7eVHRXwUQuiQjaQ="; }; }; }); in { nixosConfigurations.nixos = nixpkgs.lib.nixosSystem { inherit system; specialArgs = { inherit inputs; opencode-desktop = opencode-patched; }; modules = [ ./configuration.nix ]; }; }; } ```
Author
Owner

@jerome-benoit commented on GitHub (Feb 4, 2026):

Proposal: Replace nix-desktop.yml with cross-platform evaluation

Instead of re-enabling the full build workflow (4 native runners, ~60 min), use a Nix evaluation workflow that catches the same errors from a single Linux runner in ~2-5 min.

The outputHashes error is an evaluation-time error - nix eval catches it without building anything.

Proposed nix-eval.yml

name: nix-eval

on:
  push:
    branches: [dev]
    paths:
      - "flake.nix"
      - "flake.lock"
      - "nix/**"
      - "packages/app/**"
      - "packages/desktop/**"
      - ".github/workflows/nix-eval.yml"
  pull_request:
    paths:
      - "flake.nix"
      - "flake.lock"
      - "nix/**"
      - "packages/app/**"
      - "packages/desktop/**"
      - ".github/workflows/nix-eval.yml"
  workflow_dispatch:

jobs:
  nix-eval:
    runs-on: blacksmith-4vcpu-ubuntu-2404
    timeout-minutes: 15
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6

      - name: Setup Nix
        uses: nixbuild/nix-quick-install-action@v34

      - name: Evaluate flake outputs (all systems)
        run: |
          set -euo pipefail
          nix --version

          echo "=== Flake metadata ==="
          nix flake metadata

          echo ""
          echo "=== Flake structure ==="
          nix flake show --all-systems

          SYSTEMS="x86_64-linux aarch64-linux x86_64-darwin aarch64-darwin"
          PACKAGES="opencode desktop"

          echo ""
          echo "=== Evaluating all packages for all systems ==="
          for system in $SYSTEMS; do
            echo ""
            echo "--- $system ---"
            for pkg in $PACKAGES; do
              printf "  %s: " "$pkg"
              if nix eval ".#packages.$system.$pkg.drvPath" --raw > /dev/null 2>&1; then
                echo "✓"
              else
                echo "✗"
                echo "::error::Evaluation failed for packages.$system.$pkg"
                nix eval ".#packages.$system.$pkg.drvPath" --raw
                exit 1
              fi
            done
          done

          echo ""
          echo "=== Evaluating devShells for all systems ==="
          for system in $SYSTEMS; do
            printf "%s: " "$system"
            if nix eval ".#devShells.$system.default.drvPath" --raw > /dev/null 2>&1; then
              echo "✓"
            else
              echo "✗"
              echo "::error::Evaluation failed for devShells.$system.default"
              nix eval ".#devShells.$system.default.drvPath" --raw
              exit 1
            fi
          done

          echo ""
          echo "=== All evaluations passed ==="

Comparison

Build (nix-desktop.yml) Eval (nix-eval.yml)
Time ~60 min ~2-5 min
Runners 4 native (Linux/macOS x86/ARM) 1 Linux
Cost High Low
Packages tested desktop only opencode, desktop
Catches outputHashes errors
Catches syntax/dep errors

The nix-desktop.yml.disabled can be deleted.

@jerome-benoit commented on GitHub (Feb 4, 2026): ## Proposal: Replace `nix-desktop.yml` with cross-platform evaluation Instead of re-enabling the full build workflow (4 native runners, ~60 min), use a **Nix evaluation workflow** that catches the same errors from a single Linux runner in ~2-5 min. The `outputHashes` error is an **evaluation-time error** - `nix eval` catches it without building anything. ### Proposed `nix-eval.yml` ```yaml name: nix-eval on: push: branches: [dev] paths: - "flake.nix" - "flake.lock" - "nix/**" - "packages/app/**" - "packages/desktop/**" - ".github/workflows/nix-eval.yml" pull_request: paths: - "flake.nix" - "flake.lock" - "nix/**" - "packages/app/**" - "packages/desktop/**" - ".github/workflows/nix-eval.yml" workflow_dispatch: jobs: nix-eval: runs-on: blacksmith-4vcpu-ubuntu-2404 timeout-minutes: 15 steps: - name: Checkout repository uses: actions/checkout@v6 - name: Setup Nix uses: nixbuild/nix-quick-install-action@v34 - name: Evaluate flake outputs (all systems) run: | set -euo pipefail nix --version echo "=== Flake metadata ===" nix flake metadata echo "" echo "=== Flake structure ===" nix flake show --all-systems SYSTEMS="x86_64-linux aarch64-linux x86_64-darwin aarch64-darwin" PACKAGES="opencode desktop" echo "" echo "=== Evaluating all packages for all systems ===" for system in $SYSTEMS; do echo "" echo "--- $system ---" for pkg in $PACKAGES; do printf " %s: " "$pkg" if nix eval ".#packages.$system.$pkg.drvPath" --raw > /dev/null 2>&1; then echo "✓" else echo "✗" echo "::error::Evaluation failed for packages.$system.$pkg" nix eval ".#packages.$system.$pkg.drvPath" --raw exit 1 fi done done echo "" echo "=== Evaluating devShells for all systems ===" for system in $SYSTEMS; do printf "%s: " "$system" if nix eval ".#devShells.$system.default.drvPath" --raw > /dev/null 2>&1; then echo "✓" else echo "✗" echo "::error::Evaluation failed for devShells.$system.default" nix eval ".#devShells.$system.default.drvPath" --raw exit 1 fi done echo "" echo "=== All evaluations passed ===" ``` ### Comparison | | Build (`nix-desktop.yml`) | Eval (`nix-eval.yml`) | |---|---|---| | Time | ~60 min | ~2-5 min | | Runners | 4 native (Linux/macOS x86/ARM) | 1 Linux | | Cost | High | Low | | Packages tested | `desktop` only | `opencode`, `desktop` | | Catches `outputHashes` errors | ✓ | ✓ | | Catches syntax/dep errors | ✓ | ✓ | The `nix-desktop.yml.disabled` can be deleted.
Author
Owner

@ndrwstn commented on GitHub (Feb 4, 2026):

I don't think the PR will actually solve the problem long-term. I think we either need four runners or perhaps just abandon maintaining a flake if it's too much maintenance overhead.

@ndrwstn commented on GitHub (Feb 4, 2026): I don't think the PR will actually solve the problem long-term. I think we either need four runners or perhaps just abandon maintaining a flake if it's too much maintenance overhead.
Author
Owner

@jerome-benoit commented on GitHub (Feb 4, 2026):

I don't think the PR will actually solve the problem long-term. I think we either need four runners or perhaps just abandon maintaining a flake if it's too much maintenance overhead.

The PR is not meant to solve the issue - hence the reference and not the close -. Its description is clear. And maintaining a flake does not add overhead if an ad hoc ci is enforced. A codeflow not enforcing review and ci is actually the main source of overhead: things done get undone then redone, etc. It's fun, but not efficient.

@jerome-benoit commented on GitHub (Feb 4, 2026): > I don't think the PR will actually solve the problem long-term. I think we either need four runners or perhaps just abandon maintaining a flake if it's too much maintenance overhead. The PR is not meant to solve the issue - hence the reference and not the close -. Its description is clear. And maintaining a flake does not add overhead if an ad hoc ci is enforced. A codeflow not enforcing review and ci is actually the main source of overhead: things done get undone then redone, etc. It's fun, but not efficient.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#8303