{"record":{"id":"68fed116eb5fe367","repo":"payloadcms/payload","slug":"invalid-join-field-field-name-the-config-does","errorCode":null,"errorMessage":"Invalid join field ${field.name}. The config does not have a field '${field.on}' in collection '${field.collection}'.","messagePattern":"Invalid join field (.+?)\\. The config does not have a field '(.+?)' in collection '(.+?)'\\.","errorType":"exception","errorClass":"InvalidFieldJoin","httpStatus":500,"severity":"error","filePath":"packages/payload/src/fields/config/sanitizeJoinField.ts","lineNumber":95,"sourceCode":"        joins,\n        parentIsLocalized,\n        polymorphicJoins,\n        validateOnly: true,\n      })\n    }\n\n    if (Array.isArray(polymorphicJoins)) {\n      polymorphicJoins.push(join)\n    }\n\n    return\n  }\n\n  const joinCollection = config.collections?.find(\n    (collection) => collection.slug === field.collection,\n  )\n  if (!joinCollection) {\n    throw new InvalidFieldJoin(field)\n  }\n\n  const relationshipField = getFieldByPath({\n    fields: flattenAllFields({ cache: true, fields: joinCollection.fields }),\n    path: field.on,\n  })\n\n  if (\n    !relationshipField ||\n    (relationshipField.field.type !== 'relationship' && relationshipField.field.type !== 'upload')\n  ) {\n    throw new InvalidFieldJoin(join.field)\n  }\n\n  if (relationshipField.pathHasLocalized) {\n    join.getForeignPath = ({ locale }) => {\n      return relationshipField.localizedPath.replace('<locale>', locale!)\n    }","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/payload/src/fields/config/sanitizeJoinField.ts#L77-L113","documentation":"A join field's `collection` slug does not match any collection registered in the config. The sanitizer looks up `config.collections` for the slug and throws `InvalidFieldJoin` when nothing matches, because the join's target table does not exist.","triggerScenarios":"`{ type: 'join', collection: 'Post', on: 'owner' }` when the collection slug is actually `posts`; referencing a collection before it is defined; typo in the slug.","commonSituations":"Renaming a collection without updating join references; copy-pasting across projects with different slugs; case mismatch (`Post` vs `posts`).","solutions":["Correct the `collection` slug to exactly match a registered collection's `slug`.","Ensure the target collection is declared in `buildConfig({ collections: [...] })`.","Watch for slug casing — Payload slugs are typically lowercase plural by convention."],"exampleFix":"// before (no collection named 'Post')\n{ type: 'join', name: 'linked', collection: 'Post', on: 'owner' }\n// after\n{ type: 'join', name: 'linked', collection: 'posts', on: 'owner' }","handlingStrategy":"validation","validationCode":"function assertJoinCollectionsExist(config) {\n  const slugs = new Set(config.collections.map(c => c.slug))\n  const bad = []\n  function walk(fields) {\n    for (const f of fields) {\n      if (f?.type === 'join') {\n        const targets = Array.isArray(f.collection) ? f.collection : [f.collection]\n        for (const t of targets) if (!slugs.has(t)) bad.push(`${f.name} -> ${t}`)\n      }\n      if (Array.isArray(f?.fields)) walk(f.fields)\n    }\n  }\n  for (const c of config.collections) walk(c.fields)\n  return bad\n}","typeGuard":"function joinCollectionExists(f: any, knownSlugs: Set<string>): boolean {\n  if (f?.type !== 'join') return true\n  const targets = Array.isArray(f.collection) ? f.collection : [f.collection]\n  return targets.every((t: string) => knownSlugs.has(t))\n}","tryCatchPattern":"try {\n  await payload.init({ config })\n} catch (err) {\n  if (err?.name === 'InvalidFieldJoin') console.error('join collection not found:', err?.data)\n  throw err\n}","preventionTips":["Reference collection slugs via shared constants to prevent typos and case mismatch.","After renaming a collection, grep for `collection:` usages in join fields."],"tags":["join","relationship","config","schema","sanitization"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}