{"record":{"id":"17bf0b439f1b9f4c","repo":"payloadcms/payload","slug":"relationship-field-was-not-found","errorCode":null,"errorMessage":"Relationship field was not found","messagePattern":"Relationship field was not found","errorType":"http","errorClass":"APIError","httpStatus":500,"severity":"error","filePath":"packages/db-mongodb/src/queries/buildSearchParams.ts","lineNumber":171,"sourceCode":"              },\n            },\n          })\n\n          const field = paths[0].field\n\n          const select: Record<string, boolean> = {\n            _id: true,\n          }\n\n          let joinPath: null | string = null\n\n          if (field.type === 'join') {\n            const relationshipField = getFieldByPath({\n              fields: collectionConfig.flattenedFields,\n              path: field.on,\n            })\n            if (!relationshipField) {\n              throw new APIError('Relationship field was not found')\n            }\n\n            let path = relationshipField.localizedPath\n            if (relationshipField.pathHasLocalized && payload.config.localization) {\n              path = path.replace('<locale>', locale || payload.config.localization.defaultLocale)\n            }\n            select[path] = true\n\n            joinPath = path\n          }\n\n          if (joinPath) {\n            select[joinPath] = true\n          }\n\n          const result = await SubModel.find(subQuery).lean().select(select)\n\n          const $in: unknown[] = []","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/db-mongodb/src/queries/buildSearchParams.ts#L153-L189","documentation":"For a join-type field in a nested query, buildSearchParam resolves the join's target relationship field via getFieldByPath on the collection's flattenedFields using field.on. If no field exists at that path, it throws APIError. The join field's `on` must point to an existing relationship field on the same collection.","triggerScenarios":"A collection has a join field whose `on` value does not match any relationship field path in flattenedFields — e.g. the referenced relationship field was renamed/removed, or `on` was typed wrong.","commonSituations":"Renaming a relationship field without updating the join field's `on`; pointing `on` at a non-relationship field (group/array); config imported from another collection where the field does not exist.","solutions":["Open the collection config and confirm the join field's `on` matches an existing relationship/upload field name/path.","If the relationship field was renamed, update the join's `on` to the new name.","Ensure `on` points to a relationship-type field, not a group/array/blocks field.","Re-run payload's config validation to surface the misconfiguration at boot."],"exampleFix":"// before\n{\n  slug: 'posts',\n  fields: [\n    { name: 'author', type: 'relationship', relationTo: 'users' },\n    { name: 'comments', type: 'join', on: 'writer' }, // 'writer' does not exist\n  ],\n}\n\n// after\n{\n  slug: 'posts',\n  fields: [\n    { name: 'author', type: 'relationship', relationTo: 'users' },\n    { name: 'comments', type: 'join', on: 'author' },\n  ],\n}","handlingStrategy":"validation","validationCode":"import { getFieldByPath } from 'payload'\n\nfunction assertJoinOnExists(collectionConfig: { flattenedFields: any[] }, joinField: { type: 'join'; on: string }) {\n  if (joinField.type !== 'join') return\n  const target = getFieldByPath({ fields: collectionConfig.flattenedFields, path: joinField.on })\n  if (!target) {\n    throw new Error(`join field 'on'=\"${joinField.on}\" does not resolve to any field on the collection`)\n  }\n  if (target.type !== 'relationship' && target.type !== 'upload') {\n    throw new Error(`join 'on' must reference a relationship/upload field, got ${target.type}`)\n  }\n}","typeGuard":"function isValidJoinOn(target: unknown): target is { type: 'relationship' | 'upload' } {\n  return typeof target === 'object' && target !== null &&\n    ['relationship', 'upload'].includes((target as any).type)\n}","tryCatchPattern":"try {\n  await payload.find({ collection: 'posts', where: { 'comments.text': { like: 'x' } } })\n} catch (e) {\n  if (e instanceof APIError && e.message === 'Relationship field was not found') {\n    console.error('join field on= points to a missing relationship — fix the collection config')\n  }\n  throw e\n}","preventionTips":["Keep join fields' `on` synchronized with the target relationship field name.","Update `on` whenever the referenced relationship field is renamed.","Run payload config validation at boot to catch broken join targets early."],"tags":["db-mongodb","query","join","relationship","config","api-error"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}