{"record":{"id":"034036d1d49c582a","repo":"TryGhost/Ghost","slug":"the-url-must-be-in-a-format-like-https-x-com-you","errorCode":null,"errorMessage":"The URL must be in a format like https://x.com/yourUsername","messagePattern":"The URL must be in a format like https://x\\.com/yourUsername","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"apps/admin/src/settings/app/utils/social-urls/twitter.ts","lineNumber":12,"sourceCode":"import {createPlatformValidator} from './platform-validator';\n\n// X handles are ASCII-only by platform rule: 1–15 letters, numbers or underscores.\n// twitter.com URLs are accepted and canonicalised to x.com.\nconst twitter = createPlatformValidator({\n    domains: ['x.com', 'twitter.com'],\n    www: false,\n    pathTypes: [\n        {urlPrefix: '', storagePrefix: '@', rule: {extra: '_', min: 1, max: 15}}\n    ],\n    errors: {\n        invalidUrl: 'The URL must be in a format like https://x.com/yourUsername',\n        invalidUsername: 'Your Username is not a valid Twitter Username'\n    }\n});\n\nexport const validateTwitterUrl = twitter.validate;\nexport const twitterHandleToUrl = twitter.handleToUrl;\nexport const twitterUrlToHandle = twitter.urlToHandle;\n","sourceCodeStart":1,"sourceCodeEnd":20,"githubUrl":"https://github.com/TryGhost/Ghost/blob/47d8b0e2ad2fd4757d3bc45f46c3ac165ff8a1fe/apps/admin/src/settings/app/utils/social-urls/twitter.ts#L1-L20","documentation":"Thrown by the platform-validator engine (createPlatformValidator) for the Twitter/X definition when input is URL-shaped but cannot be resolved to a valid x.com/twitter.com profile URL. The error message is declared in twitter.ts ('The URL must be in a format like https://x.com/yourUsername') but the actual throw happens in platform-validator.ts at: URL regex non-match (line 227), no path-type prefix match or empty remainder after the prefix (line 233, e.g. 'https://x.com/' with empty username), or the built canonical URL failing validator.isURL (line 263).","triggerScenarios":"Input is detected as a URL (starts with http(s)://, //, www., or matches the bare x.com/twitter.com domain) but: the domain isn't x.com/twitter.com (e.g. 'https://facebook.com/user' → urlRegex fails → invalidUrl); OR the path after the domain is empty ('https://x.com/' → rest is '' → rest.length <= urlPrefix.length(0)); OR the assembled canonical URL fails validator.isURL. Note: bare non-URL handles that fail the username charset/length route to invalidUsername instead.","commonSituations":"User pasted a URL for the wrong platform into the X field; user entered 'https://x.com' with no handle; URL contains characters validator.isURL rejects; input had a scheme but a malformed host.","solutions":["Enter a full URL like 'https://x.com/yourUsername' or a bare handle 'yourUsername' (1–15 alphanumerics/underscores).","If pasting, confirm the URL is on x.com or twitter.com — wrong-domain URLs throw invalidUrl.","Strip whitespace and trailing slashes before submitting; an empty path after the domain is treated as invalidUrl.","For non-throwing checks in code, use twitterUrlToHandle(url) which returns null on invalid input instead of throwing."],"exampleFix":"// before — throws on wrong-domain or empty-path URL\nconst normalized = validateTwitterUrl(value);\n\n// after — non-throwing pre-check, then validate\nimport {twitterUrlToHandle, validateTwitterUrl} from './twitter';\nconst trimmed = value.trim();\ntry {\n    // twitterUrlToHandle returns null for non-x.com URLs / bad shapes\n    if (trimmed && trimmed.includes('://') && twitterUrlToHandle(trimmed) === null) {\n        setFieldError('twitter', 'Use an x.com or twitter.com URL');\n    } else {\n        setNormalized(validateTwitterUrl(trimmed));\n    }\n} catch (e) {\n    setFieldError('twitter', e instanceof Error ? e.message : 'Invalid X/Twitter URL');\n}","handlingStrategy":"try-catch","validationCode":"// Non-throwing pre-check using the URL→handle extractor\nimport {twitterUrlToHandle} from './twitter';\nfunction looksLikeTwitterUrl(input: string): boolean {\n    if (!input || !input.includes('://')) return true; // bare handles validated by the rule\n    return twitterUrlToHandle(input) !== null;\n}","typeGuard":"null","tryCatchPattern":"try {\n    const normalized = validateTwitterUrl(value.trim());\n} catch (e) {\n    setFieldError('twitter', e instanceof Error ? e.message : 'Invalid X/Twitter URL');\n}","preventionTips":["Use a full x.com/twitter.com URL or a bare handle (1–15 ASCII alphanumerics/underscores).","For non-throwing checks, use twitterUrlToHandle(url) which returns null on invalid input.","Strip whitespace and trailing slashes before validating.","Ensure the path after the domain isn't empty — 'https://x.com/' throws invalidUrl."],"tags":["twitter","x","social-urls","validation"],"backgroundTag":null,"analyzedSha":"47d8b0e2ad2fd4757d3bc45f46c3ac165ff8a1fe","analyzedAt":"2026-08-13T01:25:26.651Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}