unionlabs/union · error · Error

The Contentful export is missing the landing or learn entry

Error message

The Contentful export is missing the landing or learn entry

What it means

The importer builds the site's core data from exactly one entry of content type "landing" and one of "learn" (entryType() reads sys.contentType.sys.id). If neither find() locates one of them in preview/entries.json, the script throws because every downstream artifact (hero titles, learn page) depends on those entries existing.

Source

Thrown at site/scripts/import-contentful-export.mjs:346

  return {
    sourceId: item.sys.id,
    createdAt: item.sys.createdAt,
    updatedAt: item.sys.updatedAt,
    firstPublishedAt: item.sys.firstPublishedAt ?? null,
    publishedAt: item.sys.publishedAt ?? null,
    published: publishedEntryIds.has(item.sys.id),
  }
}

const landingEntry = preview.entries.items.find(
  (item) => entryType(item) === "landing",
)
const learnEntry = preview.entries.items.find(
  (item) => entryType(item) === "learn",
)

if (!landingEntry || !learnEntry) {
  throw new Error(
    "The Contentful export is missing the landing or learn entry",
  )
}

const landing = {
  ...sourceMetadata(landingEntry),
  entry: field(landingEntry, "entry") || "",
}
for (const prefix of ["first", "second", "third", "fourth"]) {
  landing[`${prefix}TitleHtml`] = renderTitle(
    field(landingEntry, `${prefix}Title`),
  )
  landing[`${prefix}TextHtml`] = pageRichText(
    field(landingEntry, `${prefix}Text`),
  )
}
await writeJson(join(dataDirectory, "landing.json"), landing)

View on GitHub (pinned to 031785bb6d)

Solutions

  1. Inspect what the export actually contains: jq -r '[.items[].sys.contentType.sys.id] | unique | .[]' <preview-dir>/entries.json
  2. Re-export the correct Contentful space/environment that still has the landing and learn entries
  3. If the content model was renamed, update the entryType strings in the script in the same change
  4. Verify previewDirectory and deliveryDirectory arguments both come from the same space

Example fix

// before
const landingEntry = preview.entries.items.find((item) => entryType(item) === "landing")
const learnEntry = preview.entries.items.find((item) => entryType(item) === "learn")
if (!landingEntry || !learnEntry) {
  throw new Error("The Contentful export is missing the landing or learn entry")
}

// after — name what is missing and what exists
const present = [...new Set(preview.entries.items.map(entryType))]
for (const required of ["landing", "learn"]) {
  if (!present.includes(required)) {
    throw new Error(`Export has no "${required}" entry; content types present: ${present.join(", ")}`)
  }
}
Defensive patterns

Strategy: validation

Validate before calling

# Fail fast with actionable output before running the script
jq -r '[.items[].sys.contentType.sys.id] | unique | .[]' "<preview-dir>/entries.json"
# both "landing" and "learn" must appear; if not, re-export the right space/environment

Type guard

const hasRequiredEntries = (entries) => {
  const types = new Set(entries.items.map((item) => item.sys.contentType.sys.id))
  return types.has("landing") && types.has("learn")
}

Prevention

When it happens

Trigger: The preview export's entries.items contains no item whose sys.contentType.sys.id is "landing" or "learn": wrong space or environment exported, the entries deleted in Contentful before the export was taken, content type IDs renamed in the content model, or a truncated/filtered entries.json.

Common situations: Passing a delivery directory where preview was expected, exporting with a space ID typo, a content-model refactor renaming the types, half-copied export directories, running the import against an export taken after the entries were unpublished.

Related errors


AI-assisted analysis of unionlabs/union@031785bb6d (2026-08-16). Data as JSON: /api/errors/5a113addefc598b9. Report an issue: GitHub.