All Docs
FeaturesCSI Teachable Replacement AppUpdated March 15, 2026

Known Issue: Image Block storageKey Stores CDN URL Instead of Blob Pathname

Known Issue: Image Block storageKey Stores CDN URL Instead of Blob Pathname

Status: Identified — fix pending
Affects: Courses imported from Teachable via the Inngest import pipeline
First reported: v1.0.49


Summary

When a Teachable course is imported through the platform's Inngest-based import pipeline, image blocks within lesson pages are constructed with an incorrect value in their storageKey field. The field is populated with the full Vercel Blob CDN URL rather than the relative Blob storage pathname that the rest of the system expects.

This means image assets created during a Teachable import are not correctly registered with the asset lifecycle management system and cannot be tracked, purged, or managed through the standard asset pipeline.


Technical Detail

During import materialisation (import-materialize.ts), after source images are uploaded to Vercel Blob storage, the migration step returns a CDN URL of the form:

https://<account-hash>.public.blob.vercel-storage.com/imports/abc123/image.png

The current (buggy) code assigns this URL directly to storageKey:

// ❌ What the code currently does
imageBlock.storageKey = raw.image.src;  // CDN URL after migration

However, storageKey is defined system-wide as the relative pathname within Blob storage (e.g. imports/abc123/image.png). This is the key used by:

  • The asset purge / cleanup pipeline when deleting unreferenced blobs
  • The asset audit system when reconciling stored objects
  • Any future re-signing or access-control layer that needs to resolve a blob by path

Because the stored value is a full URL rather than a pathname, lookups against assets.storageKey for these image blocks will silently fail.


Impact

What works

  • Images display correctly in the course viewer. The CDN URL stored in storageKey is still a valid public URL, so <img> tags render without issue.

What is broken

  • Asset purge pipeline — image blobs from Teachable imports will not be found by storageKey lookups and will never be cleaned up, leading to orphaned blobs in storage.
  • Asset lifecycle tracking — these assets appear invisible to management tooling.
  • Data consistencystorageKey values across the system are mixed (some relative paths, some full URLs), which complicates any future migration or query.

Workaround

There is currently no end-user workaround. Imported image content will display normally. However, be aware that storage costs may accumulate if large volumes of Teachable course images are imported before the fix is deployed, since orphaned blobs will not be purged.


Planned Fix

The fix involves updating import-materialize.ts so that after the asset migration step, the code looks up the corresponding import_assets row by source URL and retrieves the pre-recorded storageKey (relative pathname). The CDN URL continues to be used for rendering purposes but is no longer written into the storageKey column.

// ✅ Intended behaviour after fix
const importAsset = await db.importAsset.findFirst({
  where: { importId, srcUrl: raw.image.src }
});

imageBlock.storageKey = importAsset.storageKey;  // e.g. "imports/abc123/image.png"

Affected Components

ComponentFileNature of issue
Import materialisationsrc/inngest/functions/import-materialize.tsstorageKey assigned CDN URL instead of Blob pathname
Asset purge pipeline(consumer)Lookup by storageKey fails for affected image blocks

Related