Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attempting to coerce a list to a string may fail with confusing error "cannot coerce a set/function to a string" #4000

Open
lboklin opened this issue Sep 8, 2020 · 4 comments
Labels
bug error-messages Confusing messages and better diagnostics

Comments

@lboklin
Copy link

lboklin commented Sep 8, 2020

Describe the bug

Attempting to call toString on a list containing a set will produce the very confusing error:

cannot coerce a set to a string

or a list containing a function:

cannot coerce a function to a string

This can take a long time to figure out the first time it happens, as it gives the impression that its calling the list itself a set or a function.

It's especially confusing when you have an expression where you think you have excluded sets and you still end up with the error in the else branch:

$ nix eval --expr 'let f = (x: if builtins.isAttrs x then "{ ... }" else toString x); in f [ {} ]'
error: --- TypeError -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- nix
at: (1:55) from string

1| let f = (x: if builtins.isAttrs x then "{ ... }" else toString x); in f [ {} ]
|                                                       ^

cannot coerce a set to a string

Steps To Reproduce

nix eval --expr 'toString [ (x: x) ]' or nix eval --expr 'toString [ {} ]'.

Expected behavior

A more helpful error, such as

cannot coerce a list to a string because of one of its elements: cannot coerce a set to a string

nix-env --version output

nix-env (Nix) 2.4pre20200721_ff314f1

@stale
Copy link

stale bot commented Mar 16, 2021

I marked this as stale due to inactivity. → More info

@stale stale bot added the stale label Mar 16, 2021
@milahu
Copy link
Contributor

milahu commented Sep 13, 2021

i got error: cannot coerce a function to a string for passing a function to stdenv.mkDerivation

stdenv.mkDerivation {
  someFunction = x: x;
}
mkDerivation hidden in abstractions
# nix-build test.nix

with import <nixpkgs> {};
let
  npmlock2nix = rec {

    node_modules = # TRACE 7
      { src
      , lockfilePostprocess ? x: x
      , ...
      }
      @ args # TRACE 8
      :
      let
        lockfile = lockfilePostprocess {};
      in
      stdenv.mkDerivation ( # TRACE 9
        {
          version = lockfile.version;
          pname = lockfile.name;
        }
        //
        args # TRACE 10
      );

    build = # TRACE 3
      { src
      , node_modules_attrs ? {} # TRACE 4
      }:
      node_modules ( # TRACE 6
        { inherit src; }
        //
        node_modules_attrs # TRACE 5
      );
  };
in

npmlock2nix.build rec { # TRACE 2
  src = /tmp;
  node_modules_attrs = {

    # the function lockfilePostprocess will cause the error:
    # cannot coerce a function to a string
    # cos attributes for derivation must be strings
    # to reproduce the bug, lockfilePostprocess is NOT removed
    # via cleanArgs in npmlock2nix/internal.nix

    lockfilePostprocess = lockfileSet: ( # TRACE 1
      lockfileSet // {
        version = "1.2.3";
        name = "some-package";
      }
    );
  };
}

--show-trace is confusing


       at /tmp/test.nix:41:5:

           40|     # to reproduce the bug, lockfilePostprocess is NOT removed via cleanArgs in npmlock2nix/internal.nix
           41|     lockfilePostprocess = lockfileSet: (
             |     ^
           42|       lockfileSet // {

       … while evaluating the attribute 'lockfilePostprocess' of the derivation 'some-package-1.2.3'

       at /nix/store/hsyhx1ibbj3glm5b447hjp3ykbcdk6gl-nixos-21.11pre312335.8d8a28b47b7/nixos/pkgs/stdenv/generic/make-derivation.nix:205:7:

          204|     // (lib.optionalAttrs (attrs ? name || (attrs ? pname && attrs ? version)) {
          205|       name =
             |       ^
          206|         let

derivation should validate its attributes (must be strings)

or, as a proper fix: --show-trace should show more of the call stack:

  • the call to toString
  • the call to derivation
  • the call to stdenv.mkDerivation

@stale stale bot removed the stale label Sep 13, 2021
@stale
Copy link

stale bot commented Apr 16, 2022

I marked this as stale due to inactivity. → More info

@stale stale bot added the stale label Apr 16, 2022
@martin-braun
Copy link

martin-braun commented Jul 17, 2023

I hate when this error appears, it's confusing and the message doesn't help to solve the issue. --show-trace will not go far enough back to see the origin of the issue.

The issue was that I did import ./whatever.nix instead of ./whatever.nix within the imports list.

@stale stale bot removed the stale label Jul 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug error-messages Confusing messages and better diagnostics
Projects
None yet
Development

No branches or pull requests

4 participants