wasmerio/wasmer · error · anyhow::Error

No template selected

Error message

No template selected

What it means

In get_template_url, if no --template value was supplied and the command is running non-interactively, the CLI cannot show the template picker, so it bails with 'No template selected'. The library throws it because choosing a template requires either a flag or interactivity.

Source

Thrown at lib/cli/src/commands/app/create.rs:540

        &self,
        client: &WasmerClient,
    ) -> anyhow::Result<(url::Url, Option<PathBuf>)> {
        let (mut url, selected_template): (url::Url, Option<AppTemplate>) = if let Some(template) =
            &self.template
        {
            if let Ok(url) = url::Url::parse(template) {
                (url, None)
            } else if let Some(template) =
                wasmer_backend_api::query::fetch_app_template_from_slug(client, template.clone())
                    .await?
            {
                (url::Url::parse(&template.repo_url)?, Some(template))
            } else {
                anyhow::bail!("Template '{template}' not found in the registry")
            }
        } else {
            if self.non_interactive {
                anyhow::bail!("No template selected")
            }

            let theme = ColorfulTheme::default();
            let registry = self
                .env
                .registry_public_url()?
                .host_str()
                .unwrap_or("unknown_registry")
                .replace('.', "_");
            let cache_dir = self.env.cache_dir().join("templates").join(registry);

            let languages = Self::fetch_template_languages_cached(client, &cache_dir).await?;

            let items = languages.iter().map(|t| t.name.clone()).collect::<Vec<_>>();

            // Note: this should really use `dialoger::FuzzySelect`, but that
            // breaks the formatting.
            let dialog = dialoguer::Select::with_theme(&theme)

View on GitHub (pinned to 8c4b9ee9d3)

Solutions

  1. Pass --template <slug> explicitly.
  2. Drop --non-interactive to choose a template from the interactive list.
  3. Use a local manifest (--use-local-manifest) instead of a registry template in automation.

Example fix

// before
// wasmer app create --non-interactive --owner me --name app
// after
// wasmer app create --non-interactive --owner me --name app --template wasmer/hello-world
Defensive patterns

Strategy: validation

Validate before calling

if ((process.env.CI || !process.stdin.isTTY) && !args.template) {
  throw new Error('--template required when running non-interactively');
}

Type guard

fn has_template(args: &CreateArgs) -> bool {
    args.template.as_deref().map(|s| !s.trim().is_empty()).unwrap_or(false)
}

Try / catch

match result {
    Err(e) if e.to_string().contains("No template selected") => {
        eprintln!("re-run with --template <slug>");
        std::process::exit(2);
    }
    other => other?,
}

Prevention

When it happens

Trigger: Running `wasmer app create --non-interactive` without --template (and not creating from a local manifest/package).

Common situations: CI pipelines or scripts creating template-based apps without specifying which template to use.

Related errors


AI-assisted analysis of wasmerio/wasmer@8c4b9ee9d3 (2026-09-01). Data as JSON: /api/errors/f2a6cf637481f7aa. Report an issue: GitHub.