santifer/career-ops · error · Error
solidjobs: URL path must start with /public-api/offers/: ${u
Error message
solidjobs: URL path must start with /public-api/offers/: ${url} What it means
assertUrl's final check requires parsed.pathname to start with '/public-api/offers/'. It fires after parse, https, and host all pass — so the URL is a valid https://solid.jobs URL but points somewhere other than the public offers API (e.g. the marketing landing page, a division listing without the prefix, or the root).
Source
Thrown at providers/solidjobs.mjs:31
* Validates that the provided URL is a trusted SolidJobs API endpoint.
* Enforces HTTPS protocol, strict hostname matching, and required path prefix.
*
* @param {string} url - The URL string to validate.
* @returns {string} The validated URL string.
* @throws {Error} If the URL is malformed, uses non-HTTPS, has an untrusted host, or wrong path.
*/
function assertUrl(url) {
let parsed;
try {
parsed = new URL(url);
} catch {
throw new Error(`solidjobs: invalid URL: ${url}`);
}
if (parsed.protocol !== 'https:') throw new Error(`solidjobs: URL must use HTTPS: ${url}`);
if (!ALLOWED_HOSTS.has(parsed.hostname))
throw new Error(`solidjobs: untrusted hostname "${parsed.hostname}" — must be solid.jobs`);
if (!parsed.pathname.startsWith('/public-api/offers/'))
throw new Error(`solidjobs: URL path must start with /public-api/offers/: ${url}`);
return url;
}
/** @type {Provider} */
export default {
id: 'solidjobs',
/**
* Attempts to detect if the provider can handle the given entry by checking the careers_url.
* * @param {{ careers_url?: string, name?: string }} entry - The configuration entry.
* @returns {{url: string} | null} An object with the matched URL, or null if not matched.
*/
detect(entry) {
const url = entry.careers_url || '';
try {
const parsed = new URL(url);
if (parsed.hostname === 'solid.jobs' && parsed.pathname.startsWith('/public-api/offers/'))
return { url };View on GitHub (pinned to 9b17a8ac97)
Solutions
- Append the API path and a division: https://solid.jobs/public-api/offers/it
- Pick the correct division from the supported list (it, engineering, marketing, sales, hr, logistics, finances, other)
- Optionally add ?campaign=<campaign> if the API docs require one
Example fix
# before careers_url: https://solid.jobs # after careers_url: https://solid.jobs/public-api/offers/it
Defensive patterns
Strategy: validation
Validate before calling
// Ensure the API path prefix is present.
function hasOffersPath(v) {
try { return new URL(v).pathname.startsWith('/public-api/offers/'); } catch { return false; }
}
if (!hasOffersPath(entry.careers_url)) {
console.warn(`${entry.name}: solidjobs URL must include /public-api/offers/<division>`);
} Prevention
- Store the API endpoint, not the browsable landing page.
- Pick a valid division (it/engineering/marketing/sales/hr/logistics/finances/other).
When it happens
Trigger: entry.careers_url is https://solid.jobs or https://solid.jobs/it rather than https://solid.jobs/public-api/offers/<division>. The API lives under /public-api/offers/ only.
Common situations: The user pasted the browsable careers landing page instead of the API endpoint. Valid divisions are: it, engineering, marketing, sales, hr, logistics, finances, other (per the module header).
Related errors
- solidjobs: invalid URL: ${url}
- solidjobs: URL must use HTTPS: ${url}
- solidjobs: untrusted hostname "${parsed.hostname}" — must be
- glints: invalid URL: ${url}
- glints: URL must use HTTPS: ${url}
AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13).
Data as JSON: /api/errors/78c79debaecc8d01.
Report an issue: GitHub.