{"record":{"id":"db43e21f9dd2a6c4","repo":"jackwener/OpenCLI","slug":"lobsters-domain-value-is-not-a-valid-hostname","errorCode":null,"errorMessage":"lobsters domain \"${value}\" is not a valid hostname","messagePattern":"lobsters domain \"(.+?)\" is not a valid hostname","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/lobsters/domain.js","lineNumber":18,"sourceCode":"// lobsters domain — list Lobste.rs stories submitted from a specific domain.\n//\n// Hits the public `https://lobste.rs/domains/<domain>.json` endpoint\n// (returns the same per-story shape used by `lobsters tag` / `lobsters\n// hot`). Lets agents ask \"what did Lobsters surface from github.com /\n// blog.cloudflare.com / arxiv.org lately?\".\nimport { cli, Strategy } from '@jackwener/opencli/registry';\nimport { ArgumentError, CommandExecutionError, EmptyResultError } from '@jackwener/opencli/errors';\n\nconst DOMAIN_PATTERN = /^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)+$/i;\n\nfunction requireDomain(value) {\n    const s = String(value ?? '').trim().toLowerCase();\n    if (!s) {\n        throw new ArgumentError('lobsters domain is required (e.g. \"github.com\" or \"arxiv.org\")');\n    }\n    if (!DOMAIN_PATTERN.test(s)) {\n        throw new ArgumentError(`lobsters domain \"${value}\" is not a valid hostname`);\n    }\n    return s;\n}\n\nfunction requireBoundedInt(value, defaultValue, maxValue) {\n    const raw = value ?? defaultValue;\n    const n = typeof raw === 'number' ? raw : Number(raw);\n    if (!Number.isInteger(n) || n <= 0) {\n        throw new ArgumentError('lobsters limit must be a positive integer');\n    }\n    if (n > maxValue) {\n        throw new ArgumentError(`lobsters limit must be <= ${maxValue}`);\n    }\n    return n;\n}\n\ncli({\n    site: 'lobsters',","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/lobsters/domain.js#L1-L36","documentation":"Thrown by requireDomain() when the supplied value fails DOMAIN_PATTERN, which requires at least two dot-separated labels of alphanumeric/hyphen characters with no spaces, scheme, path, or trailing hyphens. The library rejects anything that is not a plain hostname before making a request.","triggerScenarios":"Passing 'https://github.com', 'github.com/', 'github .com', '-github.com', 'localhost', 'github', or a full URL into domain()/requireDomain().","commonSituations":"Users paste a full URL copied from the browser instead of the bare domain; trailing slash or path included; subdomain-only shorthand like 'en.wikipedia' lacking a TLD; uppercase is fine (pattern is case-insensitive) but spaces and schemes are not.","solutions":["Strip scheme, path, and query, leaving only the hostname: new URL(input).hostname","Ensure the value has at least two dot-separated labels, e.g. 'arxiv.org' not 'arxiv'","Remove surrounding whitespace or stray characters (quotes, trailing slash)","If a bare single label like 'localhost' is intended, note this API does not accept it"],"exampleFix":"// before\nawait cli.domain('https://github.com/trending');\n// after\nawait cli.domain(new URL('https://github.com/trending').hostname); // 'github.com'","handlingStrategy":"validation","validationCode":"const DOMAIN_PATTERN = /^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)+$/i;\nfunction isValidDomain(v) {\n  const s = String(v ?? '').trim().toLowerCase();\n  return DOMAIN_PATTERN.test(s);\n}\nif (!isValidDomain(input)) input = new URL(input).hostname;","typeGuard":"function isBareHostname(v) {\n  return typeof v === 'string' && /^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)+$/i.test(v.trim());\n}","tryCatchPattern":"try {\n  await cli.domain(input);\n} catch (err) {\n  if (err instanceof ArgumentError && /not a valid hostname/.test(err.message)) {\n    input = new URL(input.startsWith('http') ? input : `https://${input}`).hostname;\n    return cli.domain(input);\n  }\n  throw err;\n}","preventionTips":["Normalize full URLs to hostname with new URL(input).hostname before passing","Trim whitespace and strip quotes/slashes from user input","Validate with the same hostname regex in your own form/CLI parsing layer"],"tags":["argument-error","hostname-validation","input-validation","cli"],"backgroundTag":"invalid-hostname","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}