gatsbyjs/gatsby · error
Expected "Head" export to be a function got "${typeof head}"
Error message
Expected "Head" export to be a function got "${typeof head}". What it means
Thrown by headExportValidator in the Head API utility when the exported 'Head' from a page is not a function. Gatsby's Head API expects a React function component exported as `Head` that returns elements to inject into the document <head>. If the export is an object, string, class, or any non-function type, validation fails.
Source
Thrown at packages/gatsby/cache-dir/head/utils.js:29
*/
export function filterHeadProps(input) {
return {
location: {
pathname: input.location.pathname,
},
params: input.params,
data: input.data || {},
serverData: input.serverData,
pageContext: input.pageContext,
}
}
/**
* Throw error if Head export is not a valid function
*/
export function headExportValidator(head) {
if (typeof head !== `function`)
throw new Error(
`Expected "Head" export to be a function got "${typeof head}".`
)
}
/**
* Warn once for same messsage
*/
let warnOnce = _ => {}
if (process.env.NODE_ENV !== `production`) {
const warnings = new Set()
warnOnce = msg => {
if (!warnings.has(msg)) {
console.warn(msg)
}
warnings.add(msg)
}
}
View on GitHub (pinned to 8b06340921)
Solutions
- Ensure the Head export is an arrow function or function declaration: `export const Head = () => <title>...</title>`.
- Check for duplicate `Head` named exports in the same file that shadow each other.
- If Head receives props, make sure it's defined as a function that accepts props: `export const Head = ({ data }) => <title>{data.title}</title>`.
- Run TypeScript or ESLint checks to catch non-function exports of Head.
Example fix
// before — Head is a JSX element, not a function export const Head = <title>My Page</title> // after — Head is a function component export const Head = () => <title>My Page</title>
Defensive patterns
Strategy: type-guard
Type guard
// Type guard for Head exports (TypeScript)
function isValidHeadExport(head: unknown): head is React.FC {
return typeof head === 'function'
}
// Usage in a test or build check:
import * as Page from './src/pages/index'
if (Page.Head !== undefined && !isValidHeadExport(Page.Head)) {
throw new Error('Head export must be a function')
} Prevention
- Always define Head as an arrow function or function declaration, never a bare JSX element.
- Add an ESLint rule or TypeScript check that Head exports are typed as React.FC or () => JSX.Element.
- Use code review to catch accidental `export const Head = <jsx/>` patterns.
- Test Head exports in isolation during development.
When it happens
Trigger: A page or template file exports `Head` as something other than a function — e.g. `export const Head = <title>...</title>` (JSX element instead of a component), `export const Head = { title: 'x' }` (object), or the Head export is shadowed/overwritten by another named export.
Common situations: Developer writes `export const Head = <title>Home</title>` instead of `export const Head = () => <title>Home</title>`, copies a Head export from a page that used a variable, or accidentally exports a constant with the same name.
Related errors
- The prop `fluid` or `fixed` is marked as required in `${comp
- ${JSON.stringify(result)}
- You must specify either a cache or a directory
- Invalid plugin options for "gatsby-plugin-feed": "quer
- Invalid plugin options for "gatsby-plugin-feed": "qu
AI-assisted analysis of gatsbyjs/gatsby@8b06340921 (2026-08-13).
Data as JSON: /api/errors/a40aa8a8b1dc2587.
Report an issue: GitHub.