jackwener/OpenCLI · error · ArgumentError
`endoflife product "${value}" is not a valid endoflife.date
Error message
`endoflife product "${value}" is not a valid endoflife.date slug` What it means
requireProduct enforces the endoflife.date slug grammar: lowercase ASCII letters/digits start, then only [a-z0-9._-], max 80 chars (regex /^[a-z0-9][a-z0-9._-]{0,79}$/). Values failing this pattern throw an ArgumentError, since such slugs cannot be valid endoflife.date products.
Source
Thrown at clis/endoflife/utils.js:22
// LTS data for hundreds of products. Docs: https://endoflife.date/docs/api/
import { ArgumentError, CommandExecutionError, EmptyResultError } from '@jackwener/opencli/errors';
export const EOL_BASE = 'https://endoflife.date/api';
const UA = 'opencli-endoflife-adapter (+https://github.com/jackwener/opencli)';
// endoflife.date product slugs are lowercase ascii + digits + dashes / dots, up to 80 chars.
const PRODUCT = /^[a-z0-9][a-z0-9._-]{0,79}$/;
export function requireProduct(value) {
const s = String(value ?? '').trim().toLowerCase();
if (!s) {
throw new ArgumentError(
'endoflife product is required (e.g. "nodejs", "python", "ubuntu")',
'Use the slug visible at https://endoflife.date/<product>.',
);
}
if (!PRODUCT.test(s)) {
throw new ArgumentError(
`endoflife product "${value}" is not a valid endoflife.date slug`,
'Slugs are lowercase ASCII letters/digits/"._-", e.g. "nodejs", "python", "ubuntu".',
);
}
return s;
}
export function requireBoundedInt(value, defaultValue, maxValue, label = 'limit') {
const raw = value ?? defaultValue;
const n = typeof raw === 'number' ? raw : Number(raw);
if (!Number.isInteger(n) || n <= 0) {
throw new ArgumentError(`endoflife ${label} must be a positive integer`);
}
if (n > maxValue) {
throw new ArgumentError(`endoflife ${label} must be <= ${maxValue}`);
}
return n;
}View on GitHub (pinned to 49907e53dc)
Solutions
- Convert the product name to its official lowercase slug (e.g. 'Ubuntu 22.04' -> 'ubuntu', 'Node.js' -> 'nodejs')
- Check the slug at https://endoflife.date/<product>
- Strip illegal characters/spaces from the input before calling
- Normalize casing in the calling script (the function lowercases but cannot fix embedded spaces/slashes)
Example fix
// before
product('Node JS');
// after
product('nodejs'); Defensive patterns
Strategy: validation
Validate before calling
const PRODUCT = /^[a-z0-9][a-z0-9._-]{0,79}$/;
function validateSlug(v) {
const s = String(v ?? '').trim().toLowerCase();
if (!PRODUCT.test(s)) throw new Error(`"${v}" is not a valid endoflife.date slug`);
return s;
} Type guard
function isValidEolSlug(v) { return typeof v === 'string' && /^[a-z0-9][a-z0-9._-]{0,79}$/.test(v.trim().toLowerCase()); } Try / catch
try {
await eolProduct(userInput);
} catch (e) {
if (e instanceof ArgumentError && /not a valid/.test(e.message)) console.error('Use lowercase slugs like nodejs/python/ubuntu');
else throw e;
} Prevention
- Map display names to official slugs before calling (e.g. 'Node.js' -> 'nodejs')
- Normalize with trim().toLowerCase() and strip spaces/slashes first
- Keep a lookup table of the products your tooling uses
- Test inputs against the slug regex in unit tests
When it happens
Trigger: Passing values with uppercase letters, spaces, slashes, non-ASCII characters, or leading punctuation — e.g. product 'Node.js' via a path containing '/nodejs', or 'my product'.
Common situations: Users supplying display names ('Ubuntu 22.04' with spaces) instead of slugs, camelCase input, URLs pasted wholesale, shell variables containing trailing whitespace or special chars (note: input is trimmed and lowercased first, so spaces inside still fail).
Related errors
- endoflife product is required (e.g. "nodejs", "python", "ubu
- `endoflife ${label} must be a positive integer`
- bbc topic "${args.topic}" is not supported
- bbc ${label} must be a positive integer
- bbc ${label} must be <= ${maxValue}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/5017b7ca12c5b86a.
Report an issue: GitHub.