I run linkedinsalaries.com, a small site that indexes only the LinkedIn job postings which actually state a salary, normalises every figure to USD/month, and throws the rest away. Roughly 800 jobs at a time, 101 locales, static build on a Cloudflare Worker.
Last week Search Console told me something I'd been getting wrong since launch, and the failure mode is worth sharing because nothing in my own tests caught it.
The error
Invalid object type for field
applicantLocationRequirements
Critical issues prevent your page or feature from appearing in Search results.
Every remote job on the site was ineligible for the Google Jobs experience. Silently. For months.
What I had written
{
"@type": "JobPosting",
"jobLocationType": "TELECOMMUTE",
"applicantLocationRequirements": {
"@type": "AdministrativeArea",
"name": "Europe, Middle East & Africa"
}
}
That looks reasonable. AdministrativeArea is a real schema.org type, the JSON is valid, and a generic schema validator passes it happily.
Why it's wrong
Google's JobPosting spec accepts only Country for that field, and states:
At least one country is required if the job is 100% remote.
My region values aren't countries — they're multi-country zones (EMEA, Americas, APAC, worldwide-remote). So there was no single country name to put there. The correct shape is an array:
"applicantLocationRequirements": [
{ "@type": "Country", "name": "GB" },
{ "@type": "Country", "name": "DE" },
{ "@type": "Country", "name": "FR" }
]
I used ISO alpha-2 codes rather than country names, because the site renders in 101 locales and a translated country name would change per locale — the markup shouldn't.
Three things I took away
1. "Valid schema.org" and "valid for Google" are different bars. The schema.org validator reported zero errors on the broken version. Google's requirements are a stricter subset, and only Search Console tells you about the subset.
2. An absent optional property beats a malformed one. For an unrecognised region I now emit nothing at all rather than guessing. A missing optional field is valid; a wrong type is a critical error that removes the page from a feature entirely.
3. If jobLocation is present, addressCountry is mandatory. I'd been emitting PostalAddress objects where every field was undefined because the source data is free text like "Berlin, Germany". Now I parse what's actually knowable (locality, region, country) and drop jobLocation entirely when no country can be determined. I deliberately do not synthesise streetAddress or postalCode — a guessed postcode is worse than an omitted optional field.
The part that actually stung
I found this in Search Console, not in my own tests — because my test asserted the shape of my config, not the behaviour of the output. It checked that I'd typed what I meant to type. It passed happily while the markup was unusable.
So I wrote an audit that fetches the deployed HTML, parses the real JSON-LD, and asserts applicantLocationRequirements is Country on every posting. Running it against production before deploying the fix reproduced all six known issues independently. That's the property I want from a test: it should fail when reality is broken, not when my intent is mis-typed.
If you're publishing JobPosting markup, check that one field. It fails quietly and costs you the entire Google Jobs surface.
The site is free, no account, and links straight to the original LinkedIn posts. There are regional Telegram feeds too (worldwide remote, EMEA, Americas, Asia & Oceania) if you'd rather be pushed the postings than check a page. Honest caveat: only the last 7 days are kept, since cards point at live listings and a dead link wastes your time.
Top comments (0)