How it happens
You build a content workflow. The first platform you integrate is the easiest one — it has a good API, you already have an account, the output format is simple. It works well.
Months later, you add three more platforms. Each one gets a code path, a UI card, an entry in the settings. The system looks complete.
Then you publish an article and notice: only the first platform received content. The others were silently skipped.
This is the accidental default problem. The first platform is not actually the default — it just happens to have the only complete, tested code path. The others exist in the system but are never reliably exercised.
Why it is silent
The failure is invisible because there is no contract that says "all required platforms must receive content." The system does not know which platforms are required for a given article. It generates content opportunistically — if the code path exists and the conditions are met, it runs.
If a condition is subtly wrong (a missing key, a slightly different field name, an unhandled edge case), the platform is simply skipped. No error is raised. The article is published to one platform, and you assume everything worked.
Making required outputs explicit
The fix is to define required outputs declaratively, then validate that every required output was produced.
// Required platforms come from a distribution map, not from code paths
const requiredPlatforms = getPlatformsForTopic(distributionMap, article.topic);
// e.g. ["linkedin", "twitter", "reddit"] for "Politics & Society"
// Build a per-article record that tracks status for every required platform
const distributionState = buildDistributionState({
article,
distributionMap,
socialPosts,
});
// Now the system knows: linkedin is required. Is it ready?
const linkedinState = distributionState.linkedin;
if (linkedinState.textStatus === "missing") {
// Surface this explicitly — do not silently skip
throw new Error("LinkedIn post is required but missing for this article.");
}
The key shift: instead of "run this code if conditions are met," the system now has a record that says "this platform is required" and can check whether it was satisfied.
The status model
A structured per-platform record makes the problem visible:
interface PlatformState {
required: boolean;
textStatus: "missing" | "ready" | "failed";
assetStatus: "not_needed" | "missing" | "ready" | "failed";
publishStatus: "not_ready" | "ready" | "published" | "failed";
}
An article is only ready to publish when every required platform has textStatus: "ready" and assetStatus: "ready" | "not_needed".
This model turns the silent skip into a visible incomplete state. The admin UI can show "3 of 4 platforms ready" instead of implying everything is done because publishing did not throw an error.
The legacy trap
Legacy systems compound this problem. The first platform typically has the richest data — dedicated fields, stored exactly as the API expects. Later platforms often reuse whatever field names were convenient at the time.
// Original flat structure — built for one platform
const socialPosts = {
linkedin: "Here is the LinkedIn post",
twitter: "Here is the tweet",
// reddit was added later — no field, just falls through
};
When you move to a structured model, you have to explicitly map legacy fields to per-platform records — and mark platforms as missing when no legacy data exists, rather than treating absence as optional.
function buildPlatformText(platform, socialPosts) {
switch (platform) {
case "linkedin":
return socialPosts.linkedin ? { body: socialPosts.linkedin } : undefined;
case "reddit":
return socialPosts.reddit ? { body: socialPosts.reddit } : undefined;
default:
return undefined;
}
}
// Absence becomes explicit: textStatus is "missing", not "done"
const textStatus = text ? "ready" : "missing";
The broader principle
Any system that silently skips required work is a system you cannot trust. The pattern of "generate what you can and assume the rest is fine" is fine for optional outputs. It is dangerous for required ones.
Make required outputs explicit. Track their status. Surface incompleteness in the UI rather than relying on the absence of errors as a signal that everything worked.