ianstormtaylor/slate · error · Error
Properties specified for a hyperscript shorthand should be a
Error message
Properties specified for a hyperscript shorthand should be an object, but for the custom element <${tagName}> tag you passed: ${props} What it means
Thrown by normalizeElements in createHyperscript when a custom element shorthand maps a tag name to a non-object value. Each entry of the elements option must be a props object merged into the created element.
Source
Thrown at packages/slate-hyperscript/src/hyperscript.ts:114
const ret = creator(tagName, attributes, children)
return ret
}
return jsx
}
/**
* Normalize a dictionary of element shorthands into creator functions.
*/
const normalizeElements = (elements: HyperscriptShorthands) => {
const creators: HyperscriptCreators<Element> = {}
for (const tagName in elements) {
const props = elements[tagName]
if (typeof props !== 'object') {
throw new Error(
`Properties specified for a hyperscript shorthand should be an object, but for the custom element <${tagName}> tag you passed: ${props}`
)
}
creators[tagName] = (
tagName: string,
attributes: { [key: string]: any },
children: any[]
) => {
return createElement('element', { ...props, ...attributes }, children)
}
}
return creators
}
export { createHyperscript, HyperscriptCreators, HyperscriptShorthands }
View on GitHub (pinned to 72a37c701e)
Solutions
- Change every elements entry to a plain object of props, e.g. { type: 'paragraph' }
- If you need full control, provide a creator function via creators instead of elements
- Verify no entry is null/undefined/string/number before creating the hyperscript
Example fix
// before
const jsx = createHyperscript({ elements: { block: 'paragraph' } })
// after
const jsx = createHyperscript({ elements: { block: { type: 'paragraph' } } }) Defensive patterns
Strategy: type-guard
Validate before calling
for (const [tag, props] of Object.entries(elements)) {
if (typeof props !== 'object' || props === null || Array.isArray(props)) {
throw new Error(`elements.${tag} must be a props object, got ${typeof props}`)
}
} Type guard
const isElementProps = (p: unknown): p is Record<string, unknown> => typeof p === 'object' && p !== null && !Array.isArray(p)
Try / catch
null
Prevention
- Use object props for every elements entry: { type: 'paragraph' }
- Provide creator functions for advanced cases
- Centralize hyperscript config in one module and type it
When it happens
Trigger: Passing elements: { block: 'paragraph' } (a string) or elements: { block: null / 42 } to createHyperscript instead of elements: { block: { type: 'paragraph' } }.
Common situations: Confusing the elements shorthand format (assuming a string type is accepted); copy-pasting config from older hyperscript examples; passing arrays or undefined values.
Related errors
- Unexpected hyperscript child object: ${child}
- The <selection> hyperscript tag must have an <anchor> tag as
- The <selection> hyperscript tag must have a <focus> tag as a
- The <text> hyperscript tag must only contain a single node's
- The <text> hyperscript tag can only contain text conten
AI-assisted analysis of ianstormtaylor/slate@72a37c701e (2026-08-27).
Data as JSON: /api/errors/f5265d2cda18e19e.
Report an issue: GitHub.