This can lead to 404s being returned from the Pulumi Cloud because the token is invalid for any number of reasons.
One way to check this is, that you are able to navigate to the stack in the [Pulumi Cloud](https://app.pulumi.com) using the same account you are using in CI.
> Pulumi CLI is now pre-installed on GitHub Actions runners. However, if you need to install a specific version, you can always use one of the aforementioned actions.
* Ensure that the `pulumi` CLI is available in the environment across multiple steps.
In most cases, the official Pulumi installation script will try to add `pulumi` to the system `PATH` automatically.
This problem is especially prevalent for users using a Docker container-based pipeline. With most Docker container pipelines, the state of the container
does not persist across steps, so you cannot split-out the installation step of the Pulumi CLI into another step and expect to use the modified environment
in the following step. There are exceptions to this. Some CI services allow you to create a reusable template step that you can inject as a pre-cursor to other
steps. This is a way to reduce repeating the installation step every time you would like to run `pulumi` command.
### Build Tools
Pulumi invokes the build tool that corresponds to your Pulumi project's runtime. If your pipeline is missing one of these tools,
Pulumi cannot run your infrastructure app. For example, if your Pulumi project uses the `nodejs` runtime, then making sure that a valid
version of `Node` installed along with `npm` or `yarn` depending on whichever package manager you are using to manage dependencies.
#### Tips
Ensure that your Pulumi project's build tools are installed on your CI runner's build agent.
Many CI services offer built-in mechanisms to acquire language runtimes of a specific version.
For example, GitHub Actions offers the `actions/setup-node` action that can install `node`, `npm`, and `yarn`. Similarly, there is a GitHub Action for installing
the runtime for [Python](https://github.com/actions/setup-python), [Go](https://github.com/actions/setup-go), as well as [.NET](https://github.com/actions/setup-dotnet).
If you are using a Docker container-based build, consider using one of Pulumi's [SDK images](https://github.com/pulumi/pulumi/tree/master/docker#sdk-images) for your respective language.
### Restoring Dependencies
Regardless of the language you pick for your Pulumi app, you will have dependencies on at least one other package or library. You must ensure that you
restore these dependencies before running a `pulumi` command. In the case of `.NET` and `Go` runtimes, those dependencies are automatically restored for you
when you run `pulumi preview` or `pulumi update --yes`.
#### Tips
* For `nodejs` and `python` runtimes, add a step prior to running any `pulumi` commands to restore the dependencies.
* For `dotnet` and `go` runtimes, the dependencies are restored for you automatically when you run `pulumi preview` or `pulumi update --yes`.
* There is an exception to restoring dependencies automatically for `.NET` when you use a private package feed. You must ensure that the
package(s) from the private feed are accessible or you can use a [pre-built binary](/docs/concepts/projects/) with Pulumi to avoid rebuilding your `.NET` solution again.
> Note that if you do choose to use a pre-built binary, you will need to install the necessary Pulumi plugins manually using `pulumi plugin install`.
* You might be caching the library dependencies but not the Pulumi plugins. Some services offer dependency caching by capturing a specific folder and restoring
that folder when your pipeline executes. However, note that Pulumi dependencies have a post-install step that also pulls-down