Skip to content

17 template pages emit a HowTo entity with no steps #20576

Description

@CamSoper

Seventeen pages declare schema_type: howto and emit a HowTo entity with no step property at all — a how-to that describes no steps.

Affected pages

All 17 are layout: template pages under content/templates/:

content/templates/container-service/{aws,azure,gcp}/index.md
content/templates/kubernetes/{aws,azure,gcp}/index.md
content/templates/kubernetes-application/{helm-chart,web-application}/index.md
content/templates/serverless-application/{aws,azure,gcp}/index.md
content/templates/static-website/{aws,azure,gcp}/index.md
content/templates/virtual-machine/{aws,azure,gcp}/index.md

The 18th page carrying schema_type: howtocontent/what-is/mcp-for-infrastructure-as-code.md — is fine and does emit steps.

Why

layouts/partials/schema/collectors/howto-entity.html extracts steps by scanning .RawContent for numbered-list items:

{{ $rawContent := .RawContent }}
{{ $lines := split $rawContent "\n" }}

Every one of those 17 pages has zero numbered list items in its body, because they're layout: template pages — the reader-visible instructions are generated by layouts/templates/template.html from frontmatter (template.prefix, template.languages, cloud), not written as prose in the markdown. So the extractor is scanning a body that has nothing to find, and:

{{/* Add steps to schema if we found any */}}
{{ if $steps }}
  {{ $schema = merge $schema (dict "step" $steps) }}
{{ end }}

...simply never adds the key. The emitted entity still carries name, url, description, totalTime, and auto-detected tool entries — everything except the one property that makes a HowTo a HowTo.

There's already a precedent for the fix

layouts/partials/schema/collectors/main-entity.html hit this exact failure on the auto-detection path and guarded against it. Tutorial hub pages route to collection-entity.html instead, with this comment:

Emitting HowTo here produced an empty/invalid step array with no real steps to describe.

The explicit schema_type: howto branch has no equivalent guard — it dispatches to the HowTo collector unconditionally:

{{ else if eq $explicitSchema "howto" }}
  {{ $entity = partial "schema/collectors/howto-entity.html" . }}

So the lesson was learned on one path and not the other.

Possible directions

  1. Guard the explicit path the way auto-detection already does — if step extraction yields nothing, emit a different entity type rather than a stepless HowTo. Most consistent with the existing fix.
  2. Teach the collector about template pages — derive steps from the same frontmatter the template layout renders from, so these pages get real, accurate steps. Best outcome for the pages themselves, more work.
  3. Change the 17 pages' schema_type if HowTo isn't the right entity for a template gallery page in the first place.

Option 1 or 2 seems right depending on whether we want these pages to carry HowTo at all.

Notes

  • Pre-existing and unrelated to any open PR. Found while reviewing Add "How to Run AI Agents on Kubernetes with Pulumi" blog post #20550, which fixes a different bug in the same collector (a step-accumulation bug that was doubling steps on the what-is page).
  • Worth confirming what consumes HowTo markup for us today before picking a direction — Google's treatment of HowTo rich results has changed over time, so the value may be mostly for LLM/agent crawlers rather than search rich results. That affects whether option 2 is worth the effort or option 1 is sufficient.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/automationIssues relating to automation (mostly GHA workflows) and automatically generated contentarea/docs-contentIssues relating to content under pulumi.com/docskind/bugresolution/fixedThis issue was fixed

    Type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions