santifer/career-ops · error · Error

nodesk: invalid URL

Error message

nodesk: invalid URL: ${url}

What it means

The nodesk provider validates every URL it is given before use. This error is thrown by assertNodeskUrl when the input string cannot be parsed as a URL at all — i.e. new URL(url) throws (missing scheme, whitespace, malformed syntax). It fails fast so a bad config value never reaches the network layer.

Solutions

  1. Fix the URL string in the config/source so it is a complete absolute URL starting with https://
  2. Trim whitespace and remove newlines/comments accidentally included in the config value
  3. Check for unset variables/empty strings being passed in; add a default or an early check
  4. If the entry should not point at nodesk at all, remove it from the provider's input instead of forcing it through

Example fix

// before
assertNodeskUrl(process.env.NODESK_URL);
// after
const raw = (process.env.NODESK_URL || '').trim();
if (!raw) throw new Error('NODESK_URL is not set');
assertNodeskUrl(raw.startsWith('http') ? raw : `https://${raw}`);
Defensive patterns

Strategy: validation

Validate before calling

function isParsableUrl(u) { try { new URL(u); return true; } catch { return false; } }
if (!isParsableUrl(url)) throw new Error(`skipping entry: not a URL: ${url}`);

Type guard

function isAbsoluteUrl(u) {
  if (typeof u !== 'string' || u.length === 0) return false;
  try { const p = new URL(u); return !!p.protocol && !!p.hostname; } catch { return false; }
}

Try / catch

try {
  useNodesk(url);
} catch (e) {
  if (String(e.message).startsWith('nodesk: invalid URL')) {
    log.warn(`Skipping bad URL: ${url}`);
    return null;
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling assertNodeskUrl (directly or via the nodesk provider's detect/fetch path) with a string that fails the URL constructor: an empty string, 'nodesk.com/jobs' without a scheme, 'https:/wrong', or a value containing spaces or control characters.

Common situations: A careers_url in portals.yml missing the 'https://' prefix; an env-var or CLI argument that is empty because it was never set; hand-edited config introducing a stray character or truncating the URL; template placeholders left unfilled ('${URL}').

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


AI-assisted analysis of santifer/career-ops@aac998c7ed (2026-09-16). Data as JSON: /api/errors/521492b53f9788db. Report an issue: GitHub.

Appendix: source

Thrown at providers/nodesk.mjs:21

/** @typedef {import('./_types.js').Provider} Provider */

// NoDesk provider - board-wide RSS feed
// (https://nodesk.co/remote-jobs/index.xml). The feed is public, no-auth,
// and XML, so it is parsed in-process with the same tiny tag extractor
// approach as providers/personio.mjs rather than adding an XML dependency.
//
// Wire in via a `job_boards:` entry with `provider: nodesk`.

const FEED_URL = 'https://nodesk.co/remote-jobs/index.xml';
const TRUSTED_HOST = 'nodesk.co';

/** @param {string} url */
function assertNodeskUrl(url) {
  let parsed;
  try {
    parsed = new URL(url);
  } catch {
    throw new Error(`nodesk: invalid URL: ${url}`);
  }
  if (parsed.protocol !== 'https:') throw new Error(`nodesk: URL must use HTTPS: ${url}`);
  if (parsed.hostname !== TRUSTED_HOST) {
    throw new Error(`nodesk: untrusted hostname "${parsed.hostname}" - must be ${TRUSTED_HOST}`);
  }
  return url;
}

// NaN-safe Date.parse - `|| undefined` would also coerce a valid epoch 0.
function toEpochMs(value) {
  if (!value) return undefined;
  const parsed = Date.parse(value);
  return Number.isNaN(parsed) ? undefined : parsed;
}

function fallbackCompany(entry) {
  return typeof entry?.name === 'string' && entry.name.trim() ? entry.name.trim() : 'NoDesk';
}

View on GitHub (pinned to aac998c7ed)