QA & Troubleshooting: Sync, Beacons, and Verification

intermediate 8 minutes
authoring qa troubleshooting debugging

Ensure your learning content is production-ready through systematic quality assurance and effective troubleshooting techniques.

Pre-Sync Validation

Before syncing content to HubDB, validate locally to catch issues early.

1. Validate JSON Syntax

For courses and pathways, ensure valid JSON:

# Using Node.js
node -e "console.log(JSON.parse(require('fs').readFileSync('content/courses/your-course.json')))"

# Using jq (if installed)
jq . content/courses/your-course.json

# Using Python
python3 -m json.tool content/courses/your-course.json

2. Validate Front Matter

Check that module front matter is valid YAML:

# Install yaml linter
npm install -g yaml-lint

# Validate front matter
yaml-lint content/modules/your-module/README.md

3. Check Required Fields

Modules must have:

  • title
  • slug
  • difficulty
  • estimated_minutes
  • tags (array)
  • description

Courses must have:

  • slug
  • title
  • summary_markdown
  • modules (array)

Pathways must have:

  • slug
  • title
  • summary_markdown
  • courses OR modules (at least one)

4. Verify References

Ensure all referenced slugs exist:

# Check if module directories exist for a course
cat content/courses/your-course.json | jq -r '.modules[]' | while read slug; do
  if [ ! -d "content/modules/$slug" ]; then
    echo "Missing module: $slug"
  fi
done

Sync Process Troubleshooting

Running Sync Commands

Content sync:

npm run sync:content

Courses sync:

npm run sync:courses

Pathways sync:

npm run sync:pathways

Dry-Run Mode

Test without making changes:

npm run sync:courses -- --dry-run
npm run sync:pathways -- --dry-run

Common Sync Errors

Error: "Missing required field: slug"

Cause: JSON file missing required field.

Fix: Add the missing field to your JSON:

{
  "slug": "your-slug-here",
  ...
}

Error: "HUBDB_*_TABLE_ID environment variable not set"

Cause: Missing environment variable.

Fix: Ensure .env file has:

HUBDB_MODULES_TABLE_ID=12345678
HUBDB_COURSES_TABLE_ID=12345679
HUBDB_PATHWAYS_TABLE_ID=12345680

Error: "Could not read estimated_minutes for module"

Cause: Referenced module doesn't exist or has invalid front matter.

Fix:

  1. Verify module directory exists
  2. Check front matter has estimated_minutes field
  3. Ensure README.md file exists

Error: "Rate limit hit"

Cause: Too many API requests to HubSpot.

Fix: The sync script has built-in retry logic with exponential backoff. Wait for it to complete. If it persists:

  • Increase delay between requests
  • Run syncs one at a time
  • Check HubSpot API limits

Error: "Cloudflare block detected"

Cause: Cloudflare security blocking requests.

Fix:

  • The script will automatically retry after delays
  • Check if your IP is rate-limited
  • Contact HubSpot support if persistent

Error: JSON parse error

Cause: Invalid JSON syntax.

Fix:

  • Use a JSON validator
  • Check for missing commas, brackets, or quotes
  • Ensure no trailing commas
  • Use proper escaping for special characters

Environment Variable Control

SYNC_DELETE_MISSING: Prevent deleting content not in source

SYNC_DELETE_MISSING=false npm run sync:content

Use this when adding new content without wanting to remove old content.

SYNC_STRIP_LEADING_H1: Control H1 stripping

SYNC_STRIP_LEADING_H1=false npm run sync:content

SYNC_ARCHIVE_STRATEGY: How to handle archived content

SYNC_ARCHIVE_STRATEGY=tag npm run sync:content    # Soft archive
SYNC_ARCHIVE_STRATEGY=delete npm run sync:content  # Hard delete

Verifying HubDB Data

After syncing, verify data in HubDB.

Check Row Counts

Log into HubSpot and navigate to: Marketing > Files and Templates > HubDB

Check the row counts for:

  • Modules table
  • Courses table
  • Pathways table

Verify Row Data

Click into each table and spot-check:

  • Modules: title, slug, difficulty, estimated_minutes, full_content
  • Courses: title, slug, module_slugs_json, estimated_minutes
  • Pathways: title, slug, course_slugs_json or module_slugs_json

Check Published Status

Ensure tables are Published, not just in draft state:

  • Look for "Published" badge in HubDB table list
  • Click "View published version" to see live data

Page Publishing

After syncing content, publish the list and detail pages.

Publish Command

npm run publish:pages

This publishes:

  • Module list page
  • Module detail page (dynamic)
  • Course list page
  • Course detail page (dynamic)
  • Pathway list page
  • Pathway detail page (dynamic)

Verify Page Status

In HubSpot CMS:

  1. Navigate to Marketing > Website > Website Pages
  2. Search for your pages
  3. Check status shows "Published"
  4. Note the live URL

Beacon Verification

Beacons are tracking/analytics implementations that verify content is live and instrumented.

What to Check

  1. Page loads successfully - No 404 or 500 errors
  2. Content renders - Text, images, links display correctly
  3. Navigation works - Links to related content function
  4. Tracking fires - Analytics events are captured

Testing Beacons

Use browser developer tools:

1. Open your module/course/pathway page
2. Open DevTools (F12)
3. Go to Network tab
4. Filter for "beacon" or "analytics"
5. Reload page
6. Verify tracking requests fire

Taking Screenshots

For documentation and issue reporting:

  1. Open the live page
  2. Ensure full content is visible
  3. Take a full-page screenshot (browser extensions help)
  4. Annotate with any issues
  5. Save with descriptive filename: module-authoring-basics-live.png

Screenshot Tools

  • Browser built-in: Firefox has full-page screenshots
  • Extensions: Full Page Screen Capture (Chrome), Awesome Screenshot
  • Command line: Playwright, Puppeteer
  • Desktop: macOS Screenshot (Cmd+Shift+4), Windows Snipping Tool

Common Content Issues

Issue: Markdown not rendering

Symptoms: Raw markdown visible on page.

Causes:

  • Content not converted to HTML during sync
  • Template expecting markdown but receiving HTML
  • Column type mismatch in HubDB

Fix:

  • Verify sync converts markdown (check console output)
  • Confirm HubDB column is RICH_TEXT type
  • Check template uses correct rendering method

Issue: Images not displaying

Symptoms: Broken image icons.

Causes:

  • Invalid image URL
  • Image not publicly accessible
  • HTTPS/HTTP mismatch

Fix:

  • Test image URL in browser
  • Ensure images are public
  • Use HTTPS URLs
  • Check CORS settings

Issue: Links broken

Symptoms: 404 errors when clicking links.

Causes:

  • Incorrect slug references
  • Content not published
  • Path mismatch

Fix:

  • Verify linked content exists and is published
  • Check slug matches exactly (case-sensitive)
  • Use correct URL format

Issue: Content not updating

Symptoms: Old content still visible after sync.

Causes:

  • Cache not cleared
  • Table not published
  • Wrong environment

Fix:

  • Clear browser cache (Ctrl+Shift+R)
  • Verify table is published in HubDB
  • Check you're viewing the correct environment (dev vs prod)

QA Checklist

Before considering content production-ready:

Module QA:

  • Front matter complete and valid
  • Slug is lowercase with hyphens only
  • Description under 160 characters
  • Tags relevant and consistent
  • Markdown renders correctly
  • Code blocks have syntax highlighting
  • Links work
  • Images display
  • Estimated time is accurate

Course QA:

  • JSON is valid
  • All module slugs exist
  • Summary is compelling
  • Content blocks render correctly
  • Total time calculation is correct
  • Display order makes sense
  • Tags align with included modules

Pathway QA:

  • JSON is valid
  • All course/module slugs exist
  • Content blocks create good flow
  • Prerequisites clearly stated
  • Time commitment realistic
  • Progression logical

Post-Sync QA:

  • HubDB row exists
  • All fields populated correctly
  • Table is published
  • Page is published
  • Live URL works
  • Content renders correctly
  • Navigation functional
  • Beacons firing (if applicable)

Reporting Issues

When reporting content issues to GitHub:

Include

  1. Description: Clear summary of the issue
  2. Steps to reproduce: How to see the problem
  3. Expected vs actual: What should happen vs what does happen
  4. Screenshots: Visual evidence
  5. Environment: Dev, staging, production
  6. URLs: Links to affected pages
  7. HubDB data: Row counts, sample data
  8. Console logs: Any errors from sync commands

Example Issue Comment

## Issue: Module not displaying correctly

**URL**: https://example.com/module/authoring-basics

**Expected**: Module content should display with proper formatting

**Actual**: Content shows raw HTML tags

**Environment**: Production

**Screenshots**: (attached)

**HubDB Status**:
- Modules table: 11 rows (published)
- Row exists for `authoring-basics`
- `full_content` field has HTML content

**Console output from sync**: (pasted)

**Browser console errors**: None

Advanced Debugging

Enable Debug Mode

Add debug flag to sync commands:

DEBUG=* npm run sync:content

Check TypeScript Build

If sync fails mysteriously:

npm run build

Review any TypeScript compilation errors.

Inspect HubDB API Responses

Modify sync scripts temporarily to log full API responses:

const response = await hubspot.cms.hubdb.rowsApi.createTableRow(TABLE_ID, row);
console.log('API Response:', JSON.stringify(response, null, 2));

Test Locally

Before syncing, test markdown conversion locally:

import { marked } from 'marked';
const html = await marked('# Test\n\nHello world');
console.log(html);

Next Steps

You've completed the authoring workflow! You're now ready to:

  • Create comprehensive content
  • Assemble courses and pathways
  • Ensure quality through QA
  • Troubleshoot issues effectively

Resources