vuejs/vue · error · Error
createStream cannot be called without a template.
Error message
createStream cannot be called without a template.
What it means
Thrown by TemplateRenderer.createStream when called without a parsedTemplate. createStream builds a TemplateStream (a Node transform stream) that wraps the rendered content with the template's head/neck/tail as data flows through; without a template there is no wrapping to do and the stream would be meaningless. This path is reached from create-renderer.ts renderToStream only when a string template is set, so a direct call or a regression triggers it.
Source
Thrown at packages/server-renderer/src/template-renderer/index.ts:275
}
}
getUsedAsyncFiles(context: Record<string, any>): Array<Resource> | undefined {
if (
!context._mappedFiles &&
context._registeredComponents &&
this.mapFiles
) {
const registered: any[] = Array.from(context._registeredComponents)
context._mappedFiles = this.mapFiles(registered).map(normalizeFile)
}
return context._mappedFiles
}
// create a transform stream
createStream(context: Record<string, any> | undefined): TemplateStream {
if (!this.parsedTemplate) {
throw new Error('createStream cannot be called without a template.')
}
//@ts-expect-error
return new TemplateStream(this, this.parsedTemplate, context || {})
}
}
function normalizeFile(file: string): Resource {
const withoutQuery = file.replace(/\?.*/, '')
const extension = path.extname(withoutQuery).slice(1)
return {
file,
extension,
fileWithoutQuery: withoutQuery,
asType: getPreloadType(extension)
}
}
function getPreloadType(ext: string): string {View on GitHub (pinned to 9e88707940)
Solutions
- Ensure a non-empty template string is passed to createRenderer when using renderToStream with a template.
- Guard: if (templateRenderer.parsedTemplate) { stream = templateRenderer.createStream(ctx) } else { /* skip wrapping */ }.
- If no template is needed, use renderToStream without the template option — the no-template branch in create-renderer returns the raw render stream.
Example fix
// before
const renderer = createRenderer({ template: '' }) // empty
renderer.renderToStream(app) // reaches createStream with null parsedTemplate
// after
const renderer = createRenderer({
template: '<!DOCTYPE html><html><body><!--vue-ssr-outlet--></body></html>'
})
renderer.renderToStream(app) Defensive patterns
Strategy: validation
Validate before calling
function assertTemplateSetForStream(templateRenderer: any): void {
if (!templateRenderer.parsedTemplate) {
throw new Error('createStream requires a template; pass one to createRenderer.')
}
}
assertTemplateSetForStream(renderer.templateRenderer)
renderer.renderToStream(app) Type guard
function canCreateStream(tr: any): boolean {
return tr.parsedTemplate != null && typeof tr.parsedTemplate !== 'function'
} Try / catch
try {
renderer.renderToStream(app, context)
} catch (e) {
if (e.message.includes('createStream cannot be called without a template')) {
// recreate renderer with a template, or use renderToString
renderer.renderToString(app, context, cb)
} else {
throw e
}
} Prevention
- Pass a non-empty string template to createRenderer when using renderToStream with wrapping.
- Validate the template option is a non-empty string before renderer creation.
- Do not pass an empty string as template; use undefined to disable wrapping.
When it happens
Trigger: Manually invoking templateRenderer.createStream(ctx) when the renderer was constructed without a template. Hitting the else branch in renderToStream with a truthy non-function template but parsedTemplate somehow null (e.g. template was an empty string).
Common situations: Custom streaming pipeline reaches into templateRenderer.createStream. Template was set to '' (empty string) which parseTemplate receives but indexOf falls through, or template option was explicitly null after object merge.
Related errors
- render cannot be called without a template.
- function template is only supported in renderToString.
- \n[31m${err}${trace}[39m\n
- render function or template not defined in component: ${vm.$
- Content placeholder not found in template.
AI-assisted analysis of vuejs/vue@9e88707940 (2026-08-11).
Data as JSON: /api/errors/97c3fe733b9bc86d.
Report an issue: GitHub.