Budibase/budibase · error · Error
Unable to generate many link schema, "${noPrimaryName}" does
Error message
Unable to generate many link schema, "${noPrimaryName}" does not have a primary key What it means
generateManyLinkSchema builds junction tables for many-to-many relationships, which requires primary keys on both tables to compose the join columns. If either table lacks a primary key definition, it throws naming the offending table.
Source
Thrown at packages/server/src/sdk/workspace/tables/external/utils.ts:88
export function otherRelationshipType(type: RelationshipType) {
if (type === RelationshipType.MANY_TO_MANY) {
return RelationshipType.MANY_TO_MANY
}
return type === RelationshipType.ONE_TO_MANY
? RelationshipType.MANY_TO_ONE
: RelationshipType.ONE_TO_MANY
}
export function generateManyLinkSchema(
datasource: Datasource,
column: ManyToManyRelationshipFieldMetadata,
table: Table,
relatedTable: Table
): Table {
if (!table.primary || !relatedTable.primary) {
const noPrimaryName = !table.primary ? table.name : relatedTable.name
throw new Error(
`Unable to generate many link schema, "${noPrimaryName}" does not have a primary key`
)
}
const primary = table.name + table.primary[0]
const relatedPrimary = relatedTable.name + relatedTable.primary[0]
const jcTblName = generateJunctionTableName(column, table, relatedTable)
const datasourceId = datasource._id!
// first create the new table
const junctionTable: Table = {
type: "table",
_id: buildExternalTableId(datasourceId, jcTblName),
name: jcTblName,
primary: [primary, relatedPrimary],
constrained: [primary, relatedPrimary],
sourceId: datasourceId,
sourceType: TableSourceType.EXTERNAL,
schema: {
[primary]: foreignKeyStructure(primary, {View on GitHub (pinned to a81a902e9a)
Solutions
- Add a primary key to the affected table in the connected SQL database and re-sync the datasource
- Set table.primary in the Budibase table schema before creating the relationship
- Use a table with a defined primary key for the many-to-many relationship
- Refresh datasource entities so the connector re-detects keys
Example fix
// before table.primary === undefined // after table.primary = ["id"] await tables.external.save(datasourceId, table)
Defensive patterns
Strategy: validation
Validate before calling
if (!table.primary?.length || !relatedTable.primary?.length) {
throw new Error("Both tables need a primary key for many-to-many links")
} Type guard
function hasPrimaryKey(t: Table): t is Table & { primary: string[] } {
return Array.isArray(t.primary) && t.primary.length > 0
} Try / catch
try {
await tables.external.save(datasourceId, table)
} catch (err) {
if (err.message.includes("does not have a primary key")) {
// add a PK in the source DB and re-sync before retrying
}
} Prevention
- Ensure every external table has a database primary key
- Re-sync datasource after altering keys in the source DB
- Check table.primary after sync before creating relationships
When it happens
Trigger: Saving a many-to-many relationship where table.primary or relatedTable.primary is undefined/empty — typically external SQL tables synced without a detected primary key.
Common situations: Imported SQL tables without primary keys; views or tables where the connector failed to detect the PK; schema sync after a PK was dropped in the database.
Related errors
- Junction table already exists, cannot create another relatio
- Unable to generate link schema, no primary keys
- Junction table not specified for many-to-many relationship b
- Junction table '${relationship.junctionTable}' not found in
- Table ID is unknown, cannot find table
AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29).
Data as JSON: /api/errors/5ff68831e53566bd.
Report an issue: GitHub.