Automation Pipeline4 min read

My Scheduled Job Widens Its Reach the Moment a File Appears

Adding en/ja to a video pipeline taught me that language is not a parameter you add to the queue. Fonts, metadata, tokens, and the scheduler all demanded it, and what I ended up with is a system where a token file on disk, not the code, decides how far I publish.

#automation#i18n#oauth#fonts#scheduling
A diagram contrasting a pipeline with one Korean queue against one branching into per-language fonts, tokens, and queues
Adding a language was not adding a queue. It was threading one more argument through every stage.

There was one queue, and one channel

My video pipeline only knew Korean. The render hook referenced a single font, the upload script opened a single token file, and there was one publish queue. I assumed adding a language meant adding one more queue file.

It did not. The moment I added a language, nearly every stage of the pipeline demanded a language argument: the font at render time, the title and description at metadata time, which channel's token at upload time, how many iterations at schedule time. If any one stage does not receive it, the pipeline does not stop. It quietly produces something wrong.

So here is the question: in your pipeline, how far does the language value travel before some stage silently falls back to a hardcoded default?

Fonts caught me first. With one language, a single font constant was enough. Rendering Japanese requires a font that can draw kana and kanji. So I branched FONTS by language: Hiragino rounded gothic for ja, PingFang for zh, the ASCII path copied over, selected by the lang value in the config. Then I ran an actual Japanese render and looked at it to confirm kana and kanji came out intact. A font branch is not the kind of change a passing build verifies. It is verified by characters appearing on screen.

The real bottleneck was identity, not fonts

Upload ran deeper. Multiple channels means multiple credentials. I changed the function that builds the service object to take a token path, and the metadata builder to produce ko/en/ja copy per language. The daily publish script got a --lang option and became a loop over per-channel tokens and per-channel queues. Re-authentication has the same shape, so the auth check script got --lang too, so each channel can be re-authorized on its own.

One decision remained: what happens when a language has no token yet.

What would you do — fail the whole run, or skip that language?

I chose skip. If a token is missing, that language is quietly passed over and the rest publishes. One channel's expired credential blocking every publish seemed worse. But that choice created a property I did not anticipate. The existing scheduled job already runs with --lang all. Today it skips en and ja because there are no tokens. The moment those token files exist, without touching the code or the schedule, the job starts publishing to three channels that same day.

Which means the code does not decide the publishing scope. A file on disk does. That is why the OAuth runbook now has its own multi-language section: creating a channel and completing authorization is not documentation, it is a deploy trigger.

Self-diagnosis checklist

  • Can you point in the code to the exact stage where the language argument stops being passed and becomes a default?
  • Is the missing-credential behavior explicitly a failure or a skip, and who can see which one happened?
  • Is there a point where creating a single file changes the scope of an already-running scheduled job?

The honest part

The en and ja channels still have no tokens. The multi-channel publish path has never run end to end. What exists right now is two seed queues (animalface, zodiac) and a loop that skips. For zh there is only a font branch — no queue, no channel. I have no idea how the per-language metadata reads to an actual viewer, or whether per-language channels perform differently from each other. Two things are verified: Japanese glyphs render correctly into the frame, and a language without a token does not take the rest of the run down with it.

Related