TryGhost/Ghost · warning
Your Username is not a valid Mastodon Username
Error message
Your Username is not a valid Mastodon Username
What it means
Thrown by mastodonHandleToUrl when converting a stored handle to a canonical URL: the handle is empty, or doesn't match either Mastodon handle pattern (@username@instance or instance/@username), or the instance portion fails validator.isFQDN. This is the handle→URL direction, used when rendering a stored Mastodon profile link.
Source
Thrown at apps/admin/src/settings/app/utils/social-urls/mastodon.ts:49
// If there's a second @, validate that part too
if (rest.includes('@')) {
const [, userInstance] = rest.split('@');
if (!validator.isFQDN(userInstance)) {
throw new Error(errMessage);
}
}
return `https://${normalizedUrl}`;
}
throw new Error(errMessage);
}
// Converts a Mastodon handle to URL
export const mastodonHandleToUrl = (handle: string) => {
const errMessage = 'Your Username is not a valid Mastodon Username';
if (!handle) {
throw new Error(errMessage);
}
// Check if it's in @username@instance format
if (handle.match(/^@[^@]+@[^/]+$/)) {
const [username, instance] = handle.split('@').slice(1);
if (!validator.isFQDN(instance)) {
throw new Error(errMessage);
}
return `https://${instance}/@${username}`;
}
// Check if it's in instance/@username format
if (handle.match(/^[^/]+\.[^/]+\/@[^/]+(@[^/]+)?$/)) {
const [instance, rest] = handle.split('/@');
if (!validator.isFQDN(instance)) {
throw new Error(errMessage);
}
View on GitHub (pinned to 47d8b0e2ad)
Solutions
- Guard against empty handles at the call site before invoking mastodonHandleToUrl.
- Validate/normalise handles at write time using validateMastodonUrl so only well-formed handles are ever stored.
- If rendering from untrusted stored data, wrap in try-catch and fall back to omitting the link rather than crashing the UI.
- Audit stored Mastodon handles for ones that no longer pass validation after a regex/validator version change.
Example fix
// before — throws (and can crash a render) on empty/corrupt stored handle
const url = mastodonHandleToUrl(profile.mastodon);
// after — guard empty, try-catch the rest
const handle = profile.mastodon?.trim();
if (!handle) {
return null;
}
try {
return mastodonHandleToUrl(handle);
} catch {
return null; // skip rendering the link for invalid stored handles
} Defensive patterns
Strategy: try-catch
Validate before calling
// Guard empty handles before calling the converter
function safeMastodonHandleToUrl(handle: string | undefined | null): string | null {
const h = handle?.trim();
if (!h) return null;
// quick shape check before invoking the throwing converter
if (!/^@[^@]+@[^/]+$/.test(h) && !/^[^/]+\.[^/]+\/@[^/]+(@[^/]+)?$/.test(h)) return null;
return null; // caller should still try-catch for FQDN failures
} Type guard
null
Try / catch
const handle = profile.mastodon?.trim();
if (!handle) return null;
try {
return mastodonHandleToUrl(handle);
} catch {
return null; // skip rendering the link for invalid stored handles
} Prevention
- Guard handleToUrl against empty strings at the call site.
- Validate/normalise handles at write time with validateMastodonUrl so only well-formed handles are stored.
- When rendering from stored data, wrap in try-catch and fall back to omitting the link.
- Audit stored handles after validator/regex version changes.
When it happens
Trigger: mastodonHandleToUrl(handle) where handle is '' (empty → immediate throw), or handle matches ^@[^@]+@[^/]+$ / ^[^/]+\.[^/]+\/@[^/]+(@[^/]+)?$ but the instance isn't an FQDN, or handle matches neither pattern at all (e.g. 'someuser', 'user@mastodon').
Common situations: Stored handle is empty due to data corruption or incomplete migration; handle was persisted before stricter validation and doesn't conform; UI renders a profile link from a handle that was never validated; concurrent deletion left an empty string.
Related errors
- The URL must be in a format like @username@instance.tld or h
- The URL must be in a format like https://x.com/yourUsername
- Your Username is not a valid Twitter Username
- The URL must be in a format like https://www.linkedin.com/in
- Your Username is not a valid LinkedIn Username
AI-assisted analysis of TryGhost/Ghost@47d8b0e2ad (2026-08-13).
Data as JSON: /api/errors/f4a29542973a067a.
Report an issue: GitHub.