Got "snap is unusable due to missing files" error

Given

sergiusens@mirkwood:~$ snap try squashfs-root/
error: cannot try /home/sergiusens/squashfs-root: snap is unusable due to missing files;
       contact developer
sergiusens@mirkwood:~$ cat squashfs-root/meta/snap.yaml 
name: java-hello-world
version: "1.0"
summary: A java example
description: this is not much more than an example
architectures:
- amd64
confinement: strict
grade: stable
apps:
  hello:
    command: echo hello
sergiusens@mirkwood:~$ find squashfs-root/
squashfs-root/
squashfs-root/meta
squashfs-root/meta/snap.yaml

Aside from the actual error, the error message is really too vague to be useful.
I saw this while running off of beta, I have since switched back to stable and things are working again.

Indeed, the message could be better.

Given that you are pretty familiar with snapd, can you please find out why you are getting this error? The message on the tin reflects the actual logic. It’s trying to find files and can’t.

afaik from seeing discussion around the feature there should also be more details in snapd logs (though the message doesn’t say that :confused: )

It is because I have disabled the use of the wrapper script in that snapcraft creates with use of adapter: none and used a command which is found on PATH.

Previous to this dumbed down example I had something like

apps:
    hello:
        command: java ota.HelloWorld
        adapter: none
        environemnt:
            PATH: $SNAP/<path-to-java>
            CLASSPATH: $SNAP/<classpath>

The echo command should be in the default path and found on core, fore any given snap,

$ snap run --shell corebird
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

sergiusens@mirkwood:/home/sergiusens$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
sergiusens@mirkwood:/home/sergiusens$ which echo
/bin/echo

ok, then there’s a real bug as well, the checks are too precise or not smart enough

The error message definitely needs fixing.

But you say that this was working an earlier snapd release and now it doesn’t? It seems surprising that snapd was searching for application commands out of the snap path.

The fact you can access the command from the shell is completely unrelated. When you run a shell you are inside bash, with everything that this means.

OK, good to know, that is not immediately obvious.

It should still work fine if I define PATH under environment, correct? Maybe it isn’t.

Sorry, I’m still not entirely sure of what you are reporting. My comments above were attempting to clarify it.

Are you saying that “echo” in “command:” in meta/snap.yaml worked with an earlier version of snapd or not? In which version was it working on?

It shouldn’t work. If it works now, we broke compatibility and need to fix it, unfortunately. If it didn’t work, then the only thing that needs fixing is the error message.

For what it’s worth, as far as I know in any version of snapd prior to the one that warned in this way, you’d get

~$ snap try /var/tmp/java-hello-world
java-hello-world 1.0 mounted from /var/tmp/java-hello-world
~$ java-hello-world.hello 
cannot snap-exec: cannot exec "/snap/java-hello-world/x1/echo": no such file or directory
~$ 

which is exactly the sort of inscrutable error the validation is trying to avoid.

Having said this, there is a hackish “feature” that I made the validation check preserve (not because I like it but because I didn’t want to risk breaking working snaps) where you can use a relative path to the binary and it’ll work.

That is, ../../../bin/echo will work.

@chipaca An absolute path might be fine as well, maybe? What seems unwise is having “foo” meaning something inside the snap or anywhere else in arbitrary places in the filesystem of the base snap.

with /bin/echo:
cannot snap-exec: cannot exec "/snap/java-hello-world/x1/bin/echo": no such file or directory.

This is, again, before this validation check was introduced. Now instead it’ll tell you to complain to the developer (and log the errors to the journal for install and try, and to stderr for pack).

I think we want it on stderr for try as well.

@niemeyer it seems I have been masked from this behavior from using the wrappers this whole time which create something acceptable for snapd.

That said, the error at runtime,

cannot snap-exec: cannot exec "/snap/java-hello-world/x1/bin/echo": no such file or directory.

Feels a lot faster to parse than the generic error about the snap being broken and contacting the developer.

Personally, I would be fine if these cases where supported:

  • $SNAP/bin/my-app (being very explicit about the path)
  • bin/my-app (relative path, prepends $SNAP)
  • /bin/echo (absolute paths, also explicit where using utilities from the bases root is worthwhile)
1 Like

While you’re looking, could you tell us your opinion of the output of snap pack on this same broken snap?

The idea is that, as snapcraft uses snap pack, they’ll see the validation errors at that point in time.

It should be fine if snap could be installed on docker and brew installed on MacOSX and Windows

@sergiusens All of these options sound fine to me as well, and I hope it’s clear by now that everybody wants a better error message. :slight_smile:

@chipaca Thinking further about it, we should disable the relative path, as it means broken logic if the snap location changes.

As an aside: note that ‘echo’ is also a shell builtin and PATH is not used by the shell to find it when specified without a relative or absolute path (so the which echo command doesn’t test what the shell is doing). If you are testing things with bash (or dash) and only specify ‘echo’ without a relative or absolute path, then you’ll end up with the shell builtin.

I am having the same issue on disabling the creation of wrapper scripts using adapter: none .
Error message: error: cannot install snap file: snap is unusable due to missing files; contact developer

$ snap version
snap    2.36.1
snapd   2.36.1
series  16
kernel  4.4.0-112-generic

Is there a workaround or solution for this problem?

The path in command needs to be relative to the prime directory for the snap to work, wrappers take care of this which by not using them, it is not taken care of. Later version of snapcraft should be warning about this situation though.

Also stop-command(if used). That was the case for me, I had the command path relative to the prime directory but somehow missed to change the stop-command path. journalctl logs for snapd helped me to pin point the issue.