Budibase/budibase · error
Unrecognized table type ${type}
Error message
Unrecognized table type ${type} What it means
createScreen is the dispatcher for Budibase's table-detail screen templates. It accepts a `type` string that must be one of "inline", "modal", "sidePanel", or "newScreen", and routes to the matching template builder. If the type matches none of these branches, it throws this error because there is no template to generate.
Source
Thrown at packages/builder/src/templates/screenTemplating/table/index.ts:46
if (type === "sidePanel") {
return await sidePanel({
tableOrView,
permissions,
screens,
workspaceAppId,
})
}
if (type === "newScreen") {
return await newScreen({
tableOrView,
permissions,
screens,
workspaceAppId,
})
}
throw new Error(`Unrecognized table type ${type}`)
}
export default createScreen
View on GitHub (pinned to a81a902e9a)
Solutions
- Check the `type` argument at the call site and make sure it is exactly one of "inline", "modal", "sidePanel", or "newScreen"
- Log or inspect the incoming value for undefined/null or casing differences (values are lowercase, exact match)
- If you added a new layout type, add a corresponding if-branch in packages/builder/src/templates/screenTemplating/table/index.ts routing to a template builder
- Clear any stale stored layout preference in the builder UI so it re-resolves a supported type
Example fix
// before
await createScreen({ tableOrView, type: "new-screen", ... })
// after
await createScreen({ tableOrView, type: "newScreen", ... }) Defensive patterns
Strategy: validation
Validate before calling
const TABLE_SCREEN_TYPES = ["inline", "modal", "sidePanel", "newScreen"] as const
function validateScreenType(type: string) {
if (!TABLE_SCREEN_TYPES.includes(type as (typeof TABLE_SCREEN_TYPES)[number])) {
throw new Error(`type must be one of: ${TABLE_SCREEN_TYPES.join(", ")}`)
}
} Type guard
function isTableScreenType(type: string): type is "inline" | "modal" | "sidePanel" | "newScreen" {
return ["inline", "modal", "sidePanel", "newScreen"].includes(type)
} Try / catch
try {
await createScreen({ tableOrView, type, permissions, screens, workspaceAppId })
} catch (err) {
if ((err as Error).message.startsWith("Unrecognized table type")) {
console.error(`Bad screen type "${type}"; falling back to "newScreen"`)
return createScreen({ tableOrView, type: "newScreen", permissions, screens, workspaceAppId })
}
throw err
} Prevention
- Type the `type` param as a union ("inline" | "modal" | "sidePanel" | "newScreen") instead of string
- Never persist raw layout selections; re-validate stored preferences against the supported list
- Keep UI option values and the template dispatcher in sync via a shared constant/type
- Log the incoming type when it reaches createScreen to catch casing/undefined issues early
When it happens
Trigger: Calling createScreen({ type }) with a type string other than the four supported values (e.g. a typo like "new-screen", an old removed value like "table", or an undefined/null type passed from UI code that failed to resolve the user's selection).
Common situations: Custom/patched builder code passing a new screen-layout option that the template layer doesn't know; version drift where a UI component emits a type added in a newer builder but the template module is older; a stale persisted user preference containing a removed layout value.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Provided edit screen route is invalid
- Cannot render an empty flow chain
- Source table '${relationship.sourceTable}' not found in data
- Target table '${relationship.targetTable}' not found in data
- Junction table not specified for many-to-many relationship b
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/9999a8ed0043754a.
Report an issue: GitHub.