Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion skills/faceless-explainer/scripts/assemble-index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,17 @@ for (const visual of visualClips) {
const start = Number(visual.start_s);
if (!isFinite(start) || start < 0)
die(`${visual.id}: visual start_s invalid (${visual.start_s})`);
const rootDur = rootDataDuration(readFileSync(compAbs, "utf8"));
// Guard against blank/partial scene files: a worker that errors or is
// interrupted mid-write leaves an empty (or markup-less) file that exists but
// fails at render with "Composition HTML is empty or could not be parsed".
// Catch it here — before emitting data-composition-src — and re-dispatch.
const compHtml = readFileSync(compAbs, "utf8");
if (!compHtml.trim() || !/<\w/.test(compHtml)) {
die(
`visual file ${compRel} is empty or has no HTML — the worker for ${visual.id} wrote a blank/partial file. Re-dispatch that scene worker before assembling.`,
);
}
const rootDur = rootDataDuration(compHtml);
if (rootDur == null) {
anomalies.push(
`${visual.id}: could not read root data-duration from ${compRel} — skipped duration cross-check`,
Expand Down
12 changes: 11 additions & 1 deletion skills/pr-to-video/scripts/assemble-index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,17 @@ for (const visual of visualClips) {
const start = Number(visual.start_s);
if (!isFinite(start) || start < 0)
die(`${visual.id}: visual start_s invalid (${visual.start_s})`);
const rootDur = rootDataDuration(readFileSync(compAbs, "utf8"));
// Guard against blank/partial scene files: a worker that errors or is
// interrupted mid-write leaves an empty (or markup-less) file that exists but
// fails at render with "Composition HTML is empty or could not be parsed".
// Catch it here — before emitting data-composition-src — and re-dispatch.
const compHtml = readFileSync(compAbs, "utf8");
if (!compHtml.trim() || !/<\w/.test(compHtml)) {
die(
`visual file ${compRel} is empty or has no HTML — the worker for ${visual.id} wrote a blank/partial file. Re-dispatch that scene worker before assembling.`,
);
}
const rootDur = rootDataDuration(compHtml);
if (rootDur == null) {
anomalies.push(
`${visual.id}: could not read root data-duration from ${compRel} — skipped duration cross-check`,
Expand Down
12 changes: 11 additions & 1 deletion skills/product-launch-video/scripts/assemble-index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,17 @@ for (const { sid, scene } of playOrder) {
`${sid}: group_spec estimatedDuration_s missing or non-positive (${scene.estimatedDuration_s})`,
);
}
const rootDur = rootDataDuration(readFileSync(compAbs, "utf8"));
// Guard against blank/partial scene files: a worker that errors or is
// interrupted mid-write leaves an empty (or markup-less) file that exists but
// fails at render with "Composition HTML is empty or could not be parsed".
// Catch it here — before emitting data-composition-src — and re-dispatch.
const compHtml = readFileSync(compAbs, "utf8");
if (!compHtml.trim() || !/<\w/.test(compHtml)) {
die(
`scene file ${compRel} is empty or has no HTML — the worker for ${sid} wrote a blank/partial file. Re-dispatch that scene worker before assembling.`,
);
}
const rootDur = rootDataDuration(compHtml);
if (rootDur == null) {
anomalies.push(
`${sid}: could not read root data-duration from ${compRel} — skipped duration cross-check`,
Expand Down
Loading