santifer/career-ops · error · Error

nofluffjobs: invalid URL

Error message

nofluffjobs: invalid URL: ${url}

What it means

The nofluffjobs provider validates URLs with assertNoFluffUrl before use. This error is thrown when the input string fails the URL constructor — it is not a syntactically valid absolute URL. Like the other providers, it fails fast before any network activity.

Solutions

  1. Repair the URL so it is a full absolute https:// URL
  2. Check the portals.yml entry for quoting/indentation issues that truncate the value
  3. Ensure the variable feeding the URL is actually set and trimmed
  4. Remove entries that are not meant to use the NoFluffJobs provider

Example fix

// before
const url = entry.careers_url || ''; // '' -> throws
assertNoFluffUrl(url);
// after
const url = (entry.api || entry.careers_url || '').trim();
if (!url) return null; // entry is not for this provider
assertNoFluffUrl(url);
Defensive patterns

Strategy: validation

Validate before calling

function isParsableUrl(u) { try { new URL(u); return true; } catch { return false; } }
if (!isParsableUrl(entry.careers_url)) throw new Error(`bad nofluffjobs url: ${entry.careers_url}`);

Type guard

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

Try / catch

try {
  await nofluffjobs.fetch(entry, ctx);
} catch (e) {
  if (String(e.message).startsWith('nofluffjobs: invalid URL')) {
    log.warn(`Fix portals.yml entry for ${entry.company}: ${e.message}`);
    return null;
  }
  throw e;
}

Prevention

When it happens

Trigger: detectUrl/fetch handing assertNoFluffUrl a careers_url or api value that is empty, scheme-less ('nofluffjobs.com/api'), malformed ('https://', 'https:/x'), or contains whitespace/invalid characters.

Common situations: portals.yml entry with a missing or truncated URL; unset variable interpolated into the config; YAML line-wrapping or quoting mistakes splitting the URL; placeholder text left in a copied template entry.

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/b9b00543349d5c8f. Report an issue: GitHub.

Appendix: source

Thrown at providers/nofluffjobs.mjs:19

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

// NoFluffJobs provider — hits the public search posting API.
// It intentionally returns only the core scanner job fields; richer skill and
// salary metadata can be added later if the provider contract is expanded.

const ALLOWED_HOSTS = new Set(['nofluffjobs.com']);
const API_URL = 'https://nofluffjobs.com/api/search/posting';
const JOB_BASE = 'https://nofluffjobs.com/pl/job/';
const PAGE_SIZE = 20;
const MAX_PAGES = 5;

function assertNoFluffUrl(url) {
  let parsed;
  try {
    parsed = new URL(url);
  } catch {
    throw new Error(`nofluffjobs: invalid URL: ${url}`);
  }
  if (parsed.protocol !== 'https:') throw new Error(`nofluffjobs: URL must use HTTPS: ${url}`);
  if (!ALLOWED_HOSTS.has(parsed.hostname)) {
    throw new Error(`nofluffjobs: untrusted hostname "${parsed.hostname}" — must be nofluffjobs.com`);
  }
  return parsed;
}

function detectUrl(entry) {
  const url = entry.api || entry.careers_url || '';
  if (typeof url !== 'string' || !url.trim()) return null;
  try {
    return { url: assertNoFluffUrl(url).href };
  } catch {
    return null;
  }
}

View on GitHub (pinned to aac998c7ed)