jackwener/OpenCLI · error · ArgumentError
Invalid Lobsters short_id: ${args.id}
Error message
Invalid Lobsters short_id: ${args.id} What it means
Thrown at clis/lobsters/read.js:100 before any HTTP call when the positional id argument doesn't match /^[a-z0-9]+$/ — the format of Lobsters short ids (e.g. '6cmh6h'). ArgumentError means the input was malformed so fetching would be pointless; the hint suggests a lowercase alphanumeric id.
Source
Thrown at clis/lobsters/read.js:100
site: 'lobsters',
name: 'read',
access: 'read',
description: 'Read a Lobste.rs story and its comment tree',
domain: 'lobste.rs',
strategy: Strategy.PUBLIC,
browser: false,
args: [
{ name: 'id', required: true, positional: true, help: 'Lobste.rs short_id (e.g. 6cmh6h)' },
{ name: 'limit', type: 'int', default: 25, help: 'Max top-level comments' },
{ name: 'depth', type: 'int', default: 2, help: 'Max reply depth (1=no replies, 2=one level of replies, etc.)' },
{ name: 'replies', type: 'int', default: 5, help: 'Max replies shown per comment at each level' },
{ name: 'max-length', type: 'int', default: 2000, help: 'Max characters per comment body (min 100)' },
],
columns: ['type', 'author', 'score', 'text'],
func: async (args) => {
const shortId = String(args.id || '').trim();
if (!/^[a-z0-9]+$/.test(shortId)) {
throw new ArgumentError(`Invalid Lobsters short_id: ${args.id}`, 'Pass a lowercase alphanumeric id like 6cmh6h');
}
const limit = requirePositiveInt(args.limit ?? 25, 'lobsters read --limit');
const maxDepth = requirePositiveInt(args.depth ?? 2, 'lobsters read --depth');
const maxReplies = requirePositiveInt(args.replies ?? 5, 'lobsters read --replies');
const maxLength = requireMinInt(args['max-length'] ?? 2000, 100, 'lobsters read --max-length');
const story = await fetchStory(shortId);
if (!story || !story.short_id) {
throw new EmptyResultError(`lobsters/${shortId}`, 'Story not found');
}
const results = [];
// Story header — title, body (description_plain, often empty for link posts), then external url.
const storyBodyRaw = (story.description_plain || htmlToText(story.description || '')).trim();
const storyBody = storyBodyRaw.length > maxLength
? storyBodyRaw.slice(0, maxLength) + '\n... [truncated]'
: storyBodyRaw;View on GitHub (pinned to 49907e53dc)
Solutions
- Extract just the slug: for https://lobste.rs/s/6cmh6h use 6cmh6h
- Lowercase the id before passing (ids are lowercase alphanumeric only)
- Trim whitespace/quotes from the value
- Pre-validate in scripts: /^[a-z0-9]+$/.test(id) before invoking
Example fix
// before
const id = 'https://lobste.rs/s/6cmh6h';
// after
const id = 'https://lobste.rs/s/6cmh6h'.split('/s/')[1] || '';
// => '6cmh6h' Defensive patterns
Strategy: validation
Validate before calling
const shortId = String(rawId || '').trim().toLowerCase();
if (!/^[a-z0-9]+$/.test(shortId)) {
throw new Error(`Invalid Lobsters short_id: ${rawId}`);
} Type guard
function isValidLobstersId(v) {
return typeof v === 'string' && /^[a-z0-9]+$/.test(v.trim());
} Try / catch
try {
return await readLobstersStory(rawId);
} catch (e) {
if (e.message.startsWith('Invalid Lobsters short_id')) {
const m = String(rawId).match(/\/s\/([a-z0-9]+)/i);
if (m) return readLobstersStory(m[1].toLowerCase());
}
throw e;
} Prevention
- Always pass the bare slug, not the full URL
- Normalize: trim + toLowerCase before passing
- Derive the id with /lobste\.rs\/s\/([a-z0-9]+)/ when given a URL
- Validate with the same regex the CLI uses before calling
When it happens
Trigger: `lobsters read 'https://lobste.rs/s/6cmh6h'` (full URL instead of id), uppercase ids like '6CMH6H', ids containing punctuation, empty string, or whitespace-only input.
Common situations: Pasting the full story URL from a browser instead of the slug; copying an id from an HN-style link with extra characters; quoting issues in shells leaving trailing spaces; using an uppercase variant of a valid id.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- ${label} must be a positive integer
- ${label} must be an integer >= ${min}
- INVALID_ARGUMENT
- INVALID_ARGUMENT
- Collection name cannot be empty
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/7763f2c44873aef5.
Report an issue: GitHub.