gitroomhq/postiz-app · error · Error
Missing external url
Error message
Missing external url
What it means
The mentions endpoint loads the integration by body.id for the current org; if no matching record exists, Error('Invalid integration') is thrown (surfacing as 500).
Source
Thrown at apps/backend/src/api/routes/integrations.controller.ts:226
.getAllowedSocialsIntegrations()
.includes(integration)
) {
throw new Error('Integration not allowed');
}
// A provider migrated via MIGRATE_PROVIDERS reconnects through its target
// provider's OAuth: the callback lands on the target and the channel is
// migrated in place (see migrateIntegration).
const migrateTo = refresh
? this._integrationManager.getMigrationTarget(integration)
: undefined;
const integrationProvider = this._integrationManager.getSocialIntegration(
migrateTo || integration
);
if (integrationProvider.externalUrl && !externalUrl) {
throw new Error('Missing external url');
}
try {
const getExternalUrl = integrationProvider.externalUrl
? {
...(await integrationProvider.externalUrl(externalUrl)),
instanceUrl: externalUrl,
}
: undefined;
const { codeVerifier, state, url } =
await integrationProvider.generateAuthUrl(getExternalUrl);
if (refresh) {
await ioRedis.set(`refresh:${state}`, refresh, 'EX', 3600);
}
if (onboarding === 'true') {View on GitHub (pinned to 0f1647f749)
Solutions
- Reload the channel list and use a currently connected integration id
- Remove disconnected channels from any persisted drafts/schedules referencing them
- Verify the integration row exists for the active org
Example fix
// before
fetchMentions({ id: draft.integrationId });
// after
const exists = integrations.some(i => i.id === draft.integrationId);
if (exists) fetchMentions({ id: draft.integrationId });
else removeIntegrationFromDraft(draft.integrationId); Defensive patterns
Strategy: validation
Validate before calling
const list = await getIntegrations();
if (!list.some(i => i.id === body.id)) throw new Error('Channel disconnected'); Type guard
const isConnected = (id: string, list: Integration[]) => list.some(i => i.id === id);
Try / catch
try { await mentions(body); } catch (e) { if (e.message === 'Invalid integration') refreshAndDrop(body.id); else throw e; } Prevention
- Clear mentions caches when a channel disconnects
- Validate ids from drafts against the live channel list before dispatch
When it happens
Trigger: POST /integrations/mentions with an id for a channel that was disconnected, deleted, or belongs to a different organization.
Common situations: Composer still referencing a channel removed after a token expiry; multi-org tokens reused; stale client-side cache of integrations.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
AI-assisted analysis of gitroomhq/postiz-app@0f1647f749 (2026-08-27).
Data as JSON: /api/errors/16077a253b6ef1d7.
Report an issue: GitHub.