Back to Feed
article 4m read

An agent rebuilt my stylesheet with an older framework and the filename never changed

A committed CSS build got overwritten by an older major version of the framework under the same path, with nothing in the repo to explain or rebuild it, and then I went back to the CDN script and left the file behind.

Article DepthPractice

Flow

Checks before a saved stylesheet comes back

  1. 1Banner matches the pinned version

    Fail the build when the file names a different major version.

  2. 2Build tool pinned

    Exact versions, a lockfile and the config live in the repo.

  3. 3Fresh rebuild matches

    A clean copy of the repo makes the same file, or it gets labeled as copied in.

  4. 4CDN script pinned if kept

    A fixed version plus a small backup stylesheet.

  5. 5No unused generated files

    Either deleted or still linked by the page.

CSS framework versions changed under the staff scheduling page, and the page never noticed. Same link, same file name, a different major version behind it.

Where the CSS came from

The page got its CSS framework from a CDN as a script, which builds the styles inside each visitor's browser, and the framework's own documentation describes it as a development tool. It adds an outside request to every page view, and if the CDN is down, the page has no styles.

So the agent opened a branch that replaced the script with a built stylesheet saved in the repo. I merged it. That seemed like the right move.

The overwrite nobody could review

A few hours later, a different agent branch rebuilt that same stylesheet. I merged that too. The page's link didn't change, so that diff was empty, and the stylesheet is one long squashed line, so its diff was unreadable. The only clue was a short banner at the top, which now named an older major version of the framework than before.

If I saw that banner when I merged, it didn't register. Almost nobody reads the top of a squashed file in review.

Why an older version matters

Big framework versions use different class names, colors, spacing and base styles. A page written for one version and styled by the other doesn't produce an error; it just loses a rule here and a margin there. Whether my page looked different, I can't say. I never compared, and there was no test.

Nothing to rebuild it from

The repository had the generated file and none of its inputs: no package list, no lockfile, no config, no record of which pages the build read. Nobody could make the same file again from a fresh copy of the repo.

Back to the CDN

Minutes later I switched the page back to the CDN script myself. The commit doesn't say why, and I won't make one up. Another attempt on that same rebuild branch had done the same swap and deleted the file, and I didn't merge that one. Mine left the stylesheet in the repo, used by nothing.

The leftover from the edge

Earlier that day, an agent branch removed a script from the bottom of the page. It was a bot-check snippet that my edge proxy automatically adds to pages on their way out, and it was requesting a file that didn't exist. My guess is someone saved the page from a browser and pasted it back in. The repo was holding what the proxy sent once, not what I wrote.

The check I want

With a saved stylesheet, the banner can be checked against the intended version.

The check reads the version off the top of the saved file and stops the build if it isn't the major version I meant to pin.

That's not in the repo yet. The fuller answer is to pin the build tool, commit its config, and confirm a fresh rebuild matches the saved file. If I won't do that, I should label the file as copied in and note its source. If I keep the CDN script, I want a fixed version and a small backup stylesheet.

The file I left behind

I should have deleted the stylesheet or kept using it. Instead it sat there looking important and doing nothing.

What the history can't tell me

I worked from the commits only. I can't say whether the older build was on purpose, whether the page changed, or what the CDN script cost visitors. The commits carry none of that.

Keep reading

Pick up a connected idea or branch into a nearby one.

5 paths forward
Related idea

Failed uploads the cleanup couldn't find, so the replacement I built mostly refuses to delete things

A failed upload would have left its partial archive behind because the cleanup only learned the file's name from a return value. I fixed that, then built a scheduled cleanup that decides what it must keep before it deletes anything, checks every target on its own, uses a lock that dies with its owner, and retries an upload exactly once, only when it runs out of disk space or quota.

via #deployment