{"record":{"id":"813ebcd68a54e8ff","repo":"jackwener/OpenCLI","slug":"coingecko-coin-id-must-look-like-a-coingecko-slug","errorCode":null,"errorMessage":"coingecko coin id must look like a CoinGecko slug (got \"${args.id}\")","messagePattern":"coingecko coin id must look like a CoinGecko slug \\(got \"(.+?)\"\\)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/coingecko/coin.js","lineNumber":32,"sourceCode":"    domain: 'api.coingecko.com',\n    strategy: Strategy.PUBLIC,\n    browser: false,\n    args: [\n        { name: 'id', positional: true, required: true, type: 'string', help: 'CoinGecko coin id (lowercase, e.g. bitcoin / ethereum / solana).' },\n        { name: 'currency', type: 'string', default: 'usd', help: 'Quote currency (usd, cny, eur, jpy, ...).' },\n    ],\n    columns: [\n        'id', 'symbol', 'name', 'rank', 'price', 'marketCap', 'volume24h',\n        'change24hPct', 'change7dPct', 'change30dPct', 'ath', 'athDate', 'atl', 'atlDate',\n        'circulatingSupply', 'totalSupply', 'maxSupply', 'genesisDate', 'homepage',\n    ],\n    func: async (args) => {\n        const id = String(args.id ?? '').trim().toLowerCase();\n        if (!id) {\n            throw new ArgumentError('coingecko coin id cannot be empty', 'Example: opencli coingecko coin bitcoin');\n        }\n        if (!/^[a-z0-9][a-z0-9-]*$/.test(id)) {\n            throw new ArgumentError(`coingecko coin id must look like a CoinGecko slug (got \"${args.id}\")`);\n        }\n        const currency = String(args.currency ?? 'usd').trim().toLowerCase();\n        if (!/^[a-z0-9-]{2,20}$/.test(currency)) {\n            throw new ArgumentError(`coingecko currency must look like a currency slug (got \"${args.currency}\")`);\n        }\n\n        const url = new URL(`https://api.coingecko.com/api/v3/coins/${id}`);\n        url.searchParams.set('localization', 'false');\n        url.searchParams.set('tickers', 'false');\n        url.searchParams.set('market_data', 'true');\n        url.searchParams.set('community_data', 'false');\n        url.searchParams.set('developer_data', 'false');\n        url.searchParams.set('sparkline', 'false');\n\n        let resp;\n        try {\n            resp = await fetch(url, { headers: { 'User-Agent': 'Mozilla/5.0' } });\n        } catch (error) {","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/coingecko/coin.js#L14-L50","documentation":"This ArgumentError is thrown when the coin id does not match the slug pattern /^[a-z0-9][a-z0-9-]*$/. CoinGecko coin ids are lowercase slugs like 'bitcoin' or 'avalanche-2'; anything containing uppercase letters, spaces, underscores, symbols, or starting with a hyphen is rejected before an API call is made. The raw args.id is echoed in the message to show what failed validation.","triggerScenarios":"Passing an id with uppercase letters ('Bitcoin'), spaces ('lite coin'), underscores ('binance_coin'), a ticker instead of a slug ('BTC'), a URL ('https://coingecko.com/en/coins/bitcoin'), or a leading hyphen.","commonSituations":"Using the coin's display name or symbol instead of its CoinGecko id; pasting a coingecko.com URL; shell uppercasing or interpolating a symbol variable.","solutions":["Use the lowercase CoinGecko slug, e.g. `opencli coingecko coin bitcoin` not `BTC`","Lowercase the input and replace spaces/underscores with hyphens before invoking","Verify the exact id on coingecko.com (the coin's URL path segment is the id)"],"exampleFix":"// before\nopencli coingecko coin BTC\n// after\nopencli coingecko coin bitcoin","handlingStrategy":"validation","validationCode":"const slug = raw.trim().toLowerCase();\nif (!/^[a-z0-9][a-z0-9-]*$/.test(slug)) throw new Error(`Not a CoinGecko slug: ${raw}`);","typeGuard":"const isCoinGeckoSlug = (v) => typeof v === 'string' && /^[a-z0-9][a-z0-9-]*$/.test(v.trim());","tryCatchPattern":"try { await run(['coingecko', 'coin', id]); } catch (e) { if (/must look like a CoinGecko slug/.test(e.message)) { console.error('Use a lowercase slug like bitcoin, not a symbol/name.'); } }","preventionTips":["Store CoinGecko ids (slugs), not symbols or names, in your coin lists","Resolve names to ids once via /api/v3/search and cache the mapping","Lowercase and normalize inputs (spaces/underscores to hyphens) before invoking"],"tags":["cli","argument-validation","regex-validation"],"backgroundTag":"invalid-slug-format","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}