TryGhost/Ghost · warning
The URL must be in a format like https://www.threads.net/@yo
Error message
The URL must be in a format like https://www.threads.net/@yourUsername
What it means
Threads reuses the Instagram username rule (ASCII letters, numbers, underscores, periods; 1-30 chars; no leading/trailing/consecutive periods). Both the invalidUrl and invalidUsername error strings resolve to this same message. The error fires when the path segment after the domain and optional '@' prefix does not satisfy the INSTAGRAM_USERNAME_RULE, or when the input does not parse as a threads.net/threads.com URL at all.
Source
Thrown at apps/admin/src/settings/app/utils/social-urls/threads.ts:16
import {INSTAGRAM_USERNAME_RULE} from './instagram';
import {createPlatformValidator} from './platform-validator';
// Threads accounts are Instagram accounts, so the username rule is shared.
// threads.com URLs are accepted and canonicalised to www.threads.net.
const threads = createPlatformValidator({
domains: ['threads.net', 'threads.com'],
www: true,
pathTypes: [
// /@username is the canonical form, but /username also resolves (it
// redirects on threads.net), so URLs without the @ are accepted too
{urlPrefix: '@', storagePrefix: '@', rule: INSTAGRAM_USERNAME_RULE},
{urlPrefix: '', storagePrefix: '@', rule: INSTAGRAM_USERNAME_RULE}
],
errors: {
invalidUrl: 'The URL must be in a format like https://www.threads.net/@yourUsername',
invalidUsername: 'The URL must be in a format like https://www.threads.net/@yourUsername'
}
});
export const validateThreadsUrl = threads.validate;
export const threadsHandleToUrl = threads.handleToUrl;
export const threadsUrlToHandle = threads.urlToHandle;
View on GitHub (pinned to 47d8b0e2ad)
Solutions
- Ensure the username segment matches /^[a-zA-Z0-9._]+$/ with length 1-30, no leading/trailing '.', no consecutive '..'.
- Confirm the URL uses threads.net or threads.com as the domain; other domains produce invalidUrl with the same message.
- If the input is a bare handle, prefix understanding: handles without '@' are accepted because the second pathType has urlPrefix '' but storagePrefix '@'.
- Strip query strings and fragments from pasted URLs before validating, since the ?# guard rejects them as invalidUsername.
Example fix
// before (fails — leading period)
validateThreadsUrl('https://www.threads.net/@.username')
// after
validateThreadsUrl('https://www.threads.net/@username') Defensive patterns
Strategy: validation
Validate before calling
function isValidThreadsHandle(handle: string): boolean {
// INSTAGRAM_USERNAME_RULE: ASCII letters/numbers/._ , 1-30, no leading/trailing/consecutive '.'
return /^[a-zA-Z0-9._]+$/.test(handle)
&& handle.length >= 1 && handle.length <= 30
&& !handle.startsWith('.') && !handle.endsWith('.')
&& !handle.includes('..');
} Type guard
function isThreadsHandle(value: unknown): value is string {
return typeof value === 'string'
&& /^[a-zA-Z0-9._]+$/.test(value)
&& value.length >= 1 && value.length <= 30
&& !value.startsWith('.') && !value.endsWith('.')
&& !value.includes('..');
} Try / catch
try {
const url = validateThreadsUrl(input);
} catch (e) {
if (e instanceof Error && /threads\.net/.test(e.message)) {
// surface to the form field
}
throw e;
} Prevention
- Validate against the Instagram username rule before calling validateThreadsUrl.
- Strip leading '@' from typed handles before validation if you handle bare input manually.
- Ensure the URL domain is threads.net or threads.com; other domains yield the same error message.
When it happens
Trigger: Calling validateThreadsUrl, threadsHandleToUrl, or threadsUrlToHandle with a URL whose username contains non-ASCII characters, exceeds 30 characters, has leading/trailing/consecutive periods, or contains disallowed characters. Also fires as invalidUrl when the domain is not threads.net or threads.com, or the path is empty after the domain.
Common situations: User pastes a threads.net URL but the handle has an underscore-period combo like '.name' (leading period rejected by notAtBoundary), or a 35-character handle. A common paste mistake is including the full thread URL to a specific post (threads.net/@user/post/123) — the pipeline takes only the first segment so this usually works, but a handle typed with spaces fails.
Related errors
- Your Username is not a valid Bluesky Username
- The URL must be in a format like @username@instance.tld or h
- Your Username is not a valid Mastodon Username
- The URL must be in a format like https://x.com/yourUsername
- Your Username is not a valid Twitter Username
AI-assisted analysis of TryGhost/Ghost@47d8b0e2ad (2026-08-13).
Data as JSON: /api/errors/113c24428137d9e4.
Report an issue: GitHub.