The letter that hid three quarters of the museum
Digging through an old drive I found a folder called screensaver, four
commits long, last touched in April 2023. Out of habit I typed the address in the
manifest into a browser expecting nothing. It loaded. It has been sitting there serving
paintings to nobody for three and a half years.
Forty-six minutes
The git log is short enough to read as a story, and the timestamps are the good part:
- 17:42
- Initial commit — one hard-coded image URL, Hokusai's Great Wave, in an array with
// Add more image URLs hereunder it - 17:54
using met API
— the array is gone, replaced by a live query- 18:27
just paintings :)
- two days later
mobile capable
— a web manifest and a pile of iOS hacks
Twelve minutes from hand-pasting a URL to asking a museum for everything it has. That
is the entire trick, and the reason it still runs: The Met publishes its open-access
collection through an API with no key, no signup and no quota, and it answers
Access-Control-Allow-Origin: *, so a single HTML file opened from a hard
drive can call it directly. Pick a random ID from the search result, ask for the object,
set background-image, done. If the object turns out to have no photograph,
it rolls again.
The letter
Then there is the bug I only noticed now, writing this.
The Met's search endpoint insists on a q parameter. There is no "give me
everything" — so the 2023 version of me passed the single letter e as a
stand-in for nothing in particular:
search?hasImages=true&medium=Paintings&q=e
That is not a wildcard. The search matches whole words, so q=e quietly
means paintings whose catalogue text contains the word "e", and the placeholder
turns into a filter. Asking the same endpoint the same question three ways this evening:
- q=e
- 3,350 paintings — what the screensaver has been drawing from
- q=a
- 11,084 paintings
- q=painting
- 14,338 paintings
So for three and a half years it has been showing a randomly chosen quarter of the collection while believing it had all of it, and the choice of which quarter came down to which letter got typed at half past five on a Friday. It never looked broken. That is what makes it my favourite kind of bug: every single painting it served was real, and the ones it could never reach left no trace.
The other half of the same mistake is in the picture above. That load asked for
medium=Paintings and came back with an object The Met titles
Engraving — ink on paper, eighteenth century, filed under Greek and Roman Art,
photographed in its frame with the mount still showing. The filter matches catalogue
text, not the thing itself, so "paintings" quietly includes prints of Roman ruins. A
minute earlier the same page had handed me a Gauguin. Both are the real collection; only
one of them is what I asked for.
The version that only exists on the server
The copy answering at that address today matches none of the four commits. It carries
a couple of :root[sizemode="fullscreen"] selectors that appear nowhere in the
repository, and this, left in:
.test:fullscreen { background-color: red }
Someone edited the live file to chase a fullscreen bug, got it working, and never committed it — so the only copy of that version in the world was the one on the server. It has now been saved next to the repo before anything touches it.
What it wanted to be
Above the code sits a block of TODO comments, which is really a product plan written by someone who already knows they will not build it:
history of "last displayed" with artist and name.... so you can go back and find out more
strongly prefer loading landscape format artwork in landscape and vice versa
hide images behind my own API cause that's def the unique work, collecting and curating them
All three are right. The first is the one you feel within about ten seconds of watching it: a painting arrives, it is beautiful, and the page has nothing to tell you about it. The second is why portrait paintings get cropped into abstraction on a wide monitor. The third is the actual insight — the museum hands out the images for free, so the only thing worth owning is the curation.
It never got any of them, and I would rather link the thing as it was than quietly fix it eleven pages later.
Still standing
- code
- one HTML file, 7.9 KB
- dependencies
- none — no build, no framework, no key
- API
- The Met Collection API, CC0, public
- built
- April 2023, in about 46 minutes
- uptime since
- three and a half years, unattended
A single file with no dependencies is still running unchanged three and a half years later, against an API that did not break, serving art that cannot expire. Almost nothing else I have written from that year still opens.
The collection came back around, too: the side-scrolling walk I built this month is fourteen paintings from that same open-access catalogue, stitched end to end. Three years apart, same museum, same free API.