Skip to content

Fix Backstage Scaffolder Template – Template Not Executing

DodaTech Updated 2026-06-24 3 min read

In this tutorial, you'll learn about Fix Backstage Scaffolder Template. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.

You create a Backstage Scaffolder template in your catalog-info.yaml. It appears in the Create… page. You fill in the parameters and click Create. The task starts, runs for a few seconds, then fails with no helpful error β€” or the "Next" button is greyed out.

Wrong ❌

# template.yaml
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
  name: my-template
  title: My Template
  description: Creates a new service
spec:
  owner: team-platform
  type: service
  parameters:
    - title: Info
      properties:
        name:
          title: Service Name
          type: string
  steps:
    - id: fetch-template
      name: Fetch Template
      action: fetch:template
      input:
        url: ./skeleton
        values:
          name: ${{ parameters.name }}

You click **Create** β€” the task spinner appears, then:

Task failed: Step 'fetch:template' failed. Could not find template location: ./skeleton

## Right βœ…

**Correct template structure with absolute path:**

```yaml
# templates/my-service/template.yaml
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
  name: my-service-template
  title: Create a New Service
  description: Scaffolds a <a href="/backend/nodejs/">Node.js</a> service with CI/CD
spec:
  owner: team-platform
  type: service

  parameters:
    - title: Service Details
      required:
        - name
      properties:
        name:
          title: Service Name
          type: string
          description: Kebab-case name (e.g. my-service)
        owner:
          title: Owner
          type: string
          description: Team name in the catalog
          ui:field: OwnerPicker

  steps:
    - id: template
      name: Generate Service
      action: fetch:template
      input:
        url: templates/my-service/skeleton
        values:
          name: ${{ parameters.name }}
          owner: ${{ parameters.owner }}

    - id: publish
      name: Publish to GitHub
      action: publish:github
      input:
        repoUrl: github.com?owner=my-org&repo=${{ parameters.name }}
        defaultBranch: main

    - id: register
      name: Register in Catalog
      action: catalog:register
      input:
        repoContentsUrl: ${{ steps.publish.output.repoContentsUrl }}
        catalogInfoPath: /catalog-info.yaml

  output:
    links:
      - title: Open in GitHub
        url: ${{ steps.publish.output.remoteUrl }}

**Skeleton directory structure:**

templates/my-service/
β”œβ”€β”€ template.yaml
└── skeleton/
    β”œβ”€β”€ package.json
    β”œβ”€β”€ catalog-info.yaml
    └── src/
        └── index.js

Now the template runs to completion:

βœ… Task 'Create a New Service' completed successfully.
Links: Open in GitHub

## Root Cause

Scaffolder `fetch:template` resolves `url` relative to the template's location in the catalog. If the path is wrong (`./skeleton` vs `templates/my-service/skeleton`), the action can't find the template files. Missing required parameters also silently disable the **Create** button.

## Prevention

- Keep the skeleton directory alongside the template YAML, not nested inside `docs/` or `src/`.
- Use `fetch:template` with a full repo URL for remote templates (e.g. `https://github.com/my-org/skeleton`).
- Test templates with `scaffolder:dry-run` before publishing.
- Log step outputs: use `scaffolder-action:log` or add `log:output` to steps.


## Common Mistakes with scaffolder template

1. **Mixing let bindings with <- bindings in do notation, producing type errors**
2. **Overlapping type class instances that cause GHC to reject the program with ambiguous dispatch errors**
3. **Non-exhaustive pattern matches that compile with warnings then crash at runtime**

These mistakes appear frequently in real-world BACKSTAGE code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.

## Practice Exercise

**Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.**

This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.

## FAQ

<details style="margin-bottom:12px;border:1px solid #e2e8f0;border-radius:10px;overflow:hidden"><summary style="cursor:pointer;padding:14px 18px;font-weight:600;font-size:1.05rem;background:#f8fafc;border-bottom:1px solid #e2e8f0;color:#1e293b">**Q: Why is the "Create" button disabled even though I filled all fields?**</summary><div style="padding:14px 18px;color:#475569;line-height:1.7;background:#fff"><p>A: A required parameter may have a hidden validation error. Check the browser console for JSON Schema validation messages.</p>
</div></details><details style="margin-bottom:12px;border:1px solid #e2e8f0;border-radius:10px;overflow:hidden"><summary style="cursor:pointer;padding:14px 18px;font-weight:600;font-size:1.05rem;background:#f8fafc;border-bottom:1px solid #e2e8f0;color:#1e293b">**Q: Can I use custom actions in a template?**</summary><div style="padding:14px 18px;color:#475569;line-height:1.7;background:#fff"><p>A: Yes β€” register custom actions via the scaffolder backend plugin. Reference them in <code>action:</code> by the registered action name.</p>
</div></details><details style="margin-bottom:12px;border:1px solid #e2e8f0;border-radius:10px;overflow:hidden"><summary style="cursor:pointer;padding:14px 18px;font-weight:600;font-size:1.05rem;background:#f8fafc;border-bottom:1px solid #e2e8f0;color:#1e293b">**Q: How do I template files with Nunjucks?**</summary><div style="padding:14px 18px;color:#475569;line-height:1.7;background:#fff"><p>A: Scaffolder uses Nunjucks by default. Use <code>{{ name }}</code>, <code>{% if %}</code>, <code>{% for %}</code> in skeleton files.</p>
</div></details><details style="margin-bottom:12px;border:1px solid #e2e8f0;border-radius:10px;overflow:hidden"><summary style="cursor:pointer;padding:14px 18px;font-weight:600;font-size:1.05rem;background:#f8fafc;border-bottom:1px solid #e2e8f0;color:#1e293b">**Q: Can I run a template from a private repo?**</summary><div style="padding:14px 18px;color:#475569;line-height:1.7;background:#fff"><p>A: Yes β€” the scaffolder backend uses the integrations configured for the SCM provider. Ensure the token has access.</p>
</div></details>

---

*Scaffolder templates are covered in the [DodaTech Backstage Scaffolder course](https://dodatech.com/courses/backstage).*

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro