{"record":{"id":"f98db2dc9f0bce71","repo":"jackwener/OpenCLI","slug":"video-url-is-required","errorCode":null,"errorMessage":"video URL is required","messagePattern":"video URL is required","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/tiktok/utils.js","lineNumber":107,"sourceCode":"    }\n    if (text.length > COMMENT_TEXT_MAX) {\n        throw new ArgumentError(\n            `comment text must be <= ${COMMENT_TEXT_MAX} characters (got ${text.length})`,\n            'TikTok rejects long comments at submit time; trim before retrying',\n        );\n    }\n    return text;\n}\n\n// Parses a TikTok video URL into {username, videoId, url}. Rejects bad\n// shapes up-front so we never `goto()` an arbitrary page and silently\n// pretend the click target was found. Both share-style links\n// (vm.tiktok.com/...) and bare video IDs are out of scope — callers must\n// pass the canonical /@user/video/id form.\nexport function parseTikTokVideoUrl(value) {\n    const raw = String(value ?? '').trim();\n    if (!raw) {\n        throw new ArgumentError(\n            'video URL is required',\n            'Example: opencli tiktok comment https://www.tiktok.com/@user/video/1234567890 \"...\"',\n        );\n    }\n    let parsed;\n    try {\n        parsed = new URL(raw);\n    } catch {\n        throw new ArgumentError(\n            `invalid video URL: ${raw}`,\n            'Example: https://www.tiktok.com/@user/video/1234567890',\n        );\n    }\n    if (!/(^|\\.)tiktok\\.com$/i.test(parsed.hostname)) {\n        throw new ArgumentError(\n            `URL must be on tiktok.com (got ${parsed.hostname})`,\n            'Example: https://www.tiktok.com/@user/video/1234567890',\n        );","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/tiktok/utils.js#L89-L125","documentation":"parseTikTokVideoUrl requires a non-empty canonical TikTok video URL. After trimming and String-coercion, an empty value means there is nothing to parse, so an ArgumentError with a usage example is thrown.","triggerScenarios":"Calling parseTikTokVideoUrl with '', null, undefined, whitespace, or any value that coerces to an empty string (e.g. String(value ?? '').trim() === '').","commonSituations":"CLI invoked without the URL argument; shell variable unset or empty ($URL expanded to nothing); a prior extraction step returned null/undefined.","solutions":["Pass a canonical URL: opencli tiktok comment https://www.tiktok.com/@user/video/1234567890 \"...\"","Check that the shell variable holding the URL is actually set (echo \"$URL\")","Ensure the URL comes before the comment text in argument order so it is not consumed elsewhere"],"exampleFix":"// before\nparseTikTokVideoUrl(opts.url) // opts.url undefined\n// after\nif (!opts.url) throw new Error('--url is required');\nparseTikTokVideoUrl(opts.url)","handlingStrategy":"validation","validationCode":"if (!url || !String(url).trim()) throw new Error('URL argument is required');","typeGuard":"const hasUrl = (u) => typeof u === 'string' && u.trim().length > 0;","tryCatchPattern":"try { parseTikTokVideoUrl(url); } catch (e) { if (/video URL is required/.test(e.message)) console.error('Pass e.g. https://www.tiktok.com/@user/video/123'); else throw e; }","preventionTips":["Always pass the URL as the first quoted argument","Check required shell variables are non-empty before invoking (${URL:?unset})","Validate CLI args in a wrapper script before calling opencli"],"tags":["validation","missing-argument","argument-error"],"backgroundTag":"missing-required-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}