{"record":{"id":"dbc94a740bf1b777","repo":"TryGhost/Ghost","slug":"the-url-must-be-in-a-format-like-https-www-youtu","errorCode":null,"errorMessage":"The URL must be in a format like https://www.youtube.com/@yourUsername, https://www.youtube.com/user/yourUsername, or https://www.youtube.com/channel/yourChannelId","messagePattern":"The URL must be in a format like https://www\\.youtube\\.com/@yourUsername, https://www\\.youtube\\.com/user/yourUsername, or https://www\\.youtube\\.com/channel/yourChannelId","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"apps/admin/src/settings/app/utils/social-urls/youtube.ts","lineNumber":16,"sourceCode":"import {createPlatformValidator} from './platform-validator';\n\n// YouTube profile URLs come in three shapes: modern @handles (3–30 chars,\n// letters/numbers/._- with no boundary punctuation — non-Latin scripts are\n// supported), legacy /user/ usernames and /channel/ IDs (UC + 22 chars).\n// Bare input defaults to an @handle.\nconst youtube = createPlatformValidator({\n    domains: ['youtube.com'],\n    www: true,\n    pathTypes: [\n        {urlPrefix: '@', storagePrefix: '@', rule: {unicode: true, extra: '._-', min: 3, max: 30, notAtBoundary: '._-', notConsecutive: '.'}},\n        {urlPrefix: 'user/', storagePrefix: 'user/', rule: {extra: '._-', min: 1, max: 50}},\n        {urlPrefix: 'channel/', storagePrefix: 'channel/', rule: {patterns: [/^UC[a-zA-Z0-9_-]{22}$/]}}\n    ],\n    errors: {\n        invalidUrl: 'The URL must be in a format like https://www.youtube.com/@yourUsername, https://www.youtube.com/user/yourUsername, or https://www.youtube.com/channel/yourChannelId',\n        invalidUsername: 'Your Username is not a valid YouTube Username'\n    }\n});\n\nexport const validateYouTubeUrl = youtube.validate;\nexport const youtubeHandleToUrl = youtube.handleToUrl;\nexport const youtubeUrlToHandle = youtube.urlToHandle;\n","sourceCodeStart":1,"sourceCodeEnd":24,"githubUrl":"https://github.com/TryGhost/Ghost/blob/47d8b0e2ad2fd4757d3bc45f46c3ac165ff8a1fe/apps/admin/src/settings/app/utils/social-urls/youtube.ts#L1-L24","documentation":"Thrown by the platform-validator engine for the YouTube definition when input is URL-shaped but can't be resolved to a valid youtube.com profile URL. Message declared in youtube.ts (the long 'https://www.youtube.com/@yourUsername, /user/yourUsername, or /channel/yourChannelId' form); thrown in platform-validator.ts at: URL regex non-match (line 227 — wrong domain), no path-type prefix match among @/user//channel/ or empty remainder (line 233 — e.g. 'https://www.youtube.com/' with no recognised prefix, or 'https://www.youtube.com/@' with empty handle), or built URL failing validator.isURL (line 263).","triggerScenarios":"Input is URL-shaped but: the domain isn't youtube.com; the path doesn't start with '@', 'user/', or 'channel/' (e.g. 'https://www.youtube.com/watch?v=...' — a video URL, not a profile); the remainder after the prefix is empty; or the built canonical URL fails validator.isURL. Bare handles that fail the matched path-type's rule route to invalidUsername. Note '@handle' supports Unicode; 'user/' is legacy alphanumeric+._- (1–50); 'channel/' must match /^UC[a-zA-Z0-9_-]{22}$.","commonSituations":"User pasted a YouTube video/watch URL instead of a channel/profile URL; user entered 'https://www.youtube.com' with no path; user pasted a URL for a different platform; URL with characters validator.isURL rejects.","solutions":["Use one of: https://www.youtube.com/@yourHandle, https://www.youtube.com/user/yourUsername, or https://www.youtube.com/channel/UC... (22 chars after UC).","Confirm the domain is youtube.com and the path starts with @, user/, or channel/.","Ensure the segment after the prefix isn't empty.","For non-throwing checks, use youtubeUrlToHandle(url) which returns null on invalid input."],"exampleFix":"// before — throws on watch-URL or empty-path URL\nconst normalized = validateYouTubeUrl(value);\n\n// after — non-throwing pre-check, then validate\nimport {youtubeUrlToHandle, validateYouTubeUrl} from './youtube';\nconst trimmed = value.trim();\ntry {\n    if (trimmed && trimmed.includes('://') && youtubeUrlToHandle(trimmed) === null) {\n        setFieldError('youtube', 'Use youtube.com/@handle, /user/name, or /channel/UC...');\n    } else {\n        setNormalized(validateYouTubeUrl(trimmed));\n    }\n} catch (e) {\n    setFieldError('youtube', e instanceof Error ? e.message : 'Invalid YouTube URL');\n}","handlingStrategy":"try-catch","validationCode":"// Non-throwing pre-check using the URL→handle extractor\nimport {youtubeUrlToHandle} from './youtube';\nfunction looksLikeYouTubeUrl(input: string): boolean {\n    if (!input || !input.includes('://')) return true;\n    return youtubeUrlToHandle(input) !== null;\n}","typeGuard":"null","tryCatchPattern":"try {\n    const normalized = validateYouTubeUrl(value.trim());\n} catch (e) {\n    setFieldError('youtube', e instanceof Error ? e.message : 'Invalid YouTube URL');\n}","preventionTips":["Use youtube.com/@handle, /user/name, or /channel/UC... (22 chars after UC).","Ensure the path after the prefix isn't empty.","Use youtubeUrlToHandle for non-throwing URL checks.","Don't mix conventions (user/@name) — a leftover @ after a structural prefix is intentionally not stripped."],"tags":["youtube","social-urls","validation"],"backgroundTag":null,"analyzedSha":"47d8b0e2ad2fd4757d3bc45f46c3ac165ff8a1fe","analyzedAt":"2026-08-13T01:25:26.651Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}