This page lists common problems and work-arounds.

This page needs expansion! If you encounter a new problem and solve it, feel free to add it here. If you encounter a problem you don't know how to solve, try asking on Stack Overflow, and be sure to add the "sandstorm.io" tag to your question. Or, talk to us on IRC (#sandstorm on libera.chat) or sandstorm-dev.

Note that language-specific issues should be documented in the language-specific guide pages, namely:

Getting a shell in the context of the grain

vagrant-spk enter-grain allows you to run a shell (e.g. bash) in the context of a grain. This can illuminate why an app is behaving in a particular way. For details and limitations, read the docs about the vagrant-spk enter-grain command.

Sandstorm apps cannot navigate the user away from the app. Therefore, app authors should set target="_blank" on external links within the app.

A convenient way to do this automatically for all links in the page is to add the following HTML to your document's <head>:

<base target="_blank">

However, if you have both internal and external links, you can add a script such as the following which will only set the target on external links:

window.onload = function(){
    var a = document.getElementsByTagName('a');
    for (var i=0; i<a.length; i++){
        if(a[i].hostname != location.hostname) {
            a[i].setAttribute('target', '_blank');
        }
    }
}

A blank white screen renders where the app should be

This can happen when a Sandstorm app in development doesn't know its correct base URL and serves a HTTP redirect away from the Sandstorm server. Sandstorm blocks that redirect, resulting in a white grain frame.

To find out if you're running into this issue, open the Javascript console in your browser and look for a Content-Security-Policy violation. If you see a message about navigation being blocked, then very likely you are seeing this error.

If possible, configure the app to use a base URL of '', literally the empty string. Then it will send HTTP redirects without specifying a base URL. If that isn't possible, Sandstorm apps should look at the Host: header for a base URL.

KeyError: 'getpwuid(): uid not found: 1000'

This is a Python bug. See the Python packaging guide for a work-around.

EROFS or "Read-only filesystem"

Only the /var directory is writable; the rest of the filesystem (which contains the contents of your app package) is read-only.

If your app wants to write to locations other than /var, and it's not easy to change the app's code, one work-around is to create a symlink from the location you app wants to modify to a location under /var. This won't work for all applications however.

ETag data

Web apps often use the ETag HTTP response header to control caching. In Sandstorm, this header is permitted so long as it follows the HTTP specification's requirement that the header values are formatted with double-quote marks, like: ETag: "value" or ETag: W/"value".

Some apps use strings without quotation marks in their ETag headers, such as ETag: value, which violates the HTTP standard. Sandstorm does not permit invalid header values because ambiguity can lead to security problems. Therefore, Sandstorm will drop invalid ETag headers and will write a warning to the grain's debug log. Usually, this does not affect app functionality, other than to reduce the effectiveness of the browser's cache.

HTTP headers are processed within the grain at the sandstorm-http-bridge layer. Recent versions of sandstorm-http-bridge drop the header and log a message. In versions v0.177 and earlier of sandstorm-http-bridge, invalid ETag data would trigger an exception, causing the request to fail.

SPK is missing files, but app works in dev mode

Sandstorm packages, when "packed" into an SPK file, must contain all files needed by the app. Those files are typically specified in .sandstorm/sandstorm-files.list and detected when the app runs in dev mode. Further files can be specified via an alwaysInclude directive in .sandstorm/sandstorm-pkgdef.capnp. Some apps hard-code all files in .sandstorm/sandstorm-files.list rather than relying on auto-detection. In any event, if the app needs a file that is missing in the Sandstorm package, the file must be added.

Note that paths begin without a slash character. For example, to include /path/to/include, one types path/to/include into the alwaysInclude line or the sandstorm-files.list file.

How to identify this error: Sometimes the app will crash (HTTP response code 500 Server Error) if it is affected by this problem. Often a "No such file" or "No such module" error appears in the grain log, similar to the following.

Warning: require_once(path/to/file.php): failed to open stream: No such file or directory

or

ImportError: No such module requests

How to fix the problem: Our recommendations are as follows.

How file auto-detection works. At each launch of spk dev (equivalently, each launch of vagrant-spk dev), a FUSE filesystem is created that watches all filesystem operations by the app. When the spk dev session terminates, any files that the app open()d are logged into .sandstorm/sandstorm-files.list. This skips any files that are merely stat()d. Because some apps know their full list of dependencies, the .sandstorm/sandstorm-pkgdef.capnp file is not written if the alwaysInclude line contains ".", which has the meaning of "include all files that the app can see." The meteor platform stack takes advantage of this feature.