QA & Troubleshooting: Sync, Beacons, and Verification
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:
- Verify module directory exists
- Check front matter has
estimated_minutes
field - 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:
- Navigate to Marketing > Website > Website Pages
- Search for your pages
- Check status shows "Published"
- Note the live URL
Beacon Verification
Beacons are tracking/analytics implementations that verify content is live and instrumented.
What to Check
- Page loads successfully - No 404 or 500 errors
- Content renders - Text, images, links display correctly
- Navigation works - Links to related content function
- 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:
- Open the live page
- Ensure full content is visible
- Take a full-page screenshot (browser extensions help)
- Annotate with any issues
- 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
- Description: Clear summary of the issue
- Steps to reproduce: How to see the problem
- Expected vs actual: What should happen vs what does happen
- Screenshots: Visual evidence
- Environment: Dev, staging, production
- URLs: Links to affected pages
- HubDB data: Row counts, sample data
- 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