paperclipai/paperclip · error · TeamsServiceUrlValidationError
Teams destination contains an invalid service URL
Error message
Teams destination contains an invalid service URL
What it means
normalizedTeamsServiceUrl parses the serviceUrl with the URL constructor; if parsing fails it throws TeamsServiceUrlValidationError with 'Teams destination contains an invalid service URL'. This rejects strings that are not syntactically valid absolute URLs.
Source
Thrown at server/src/services/chat-sdk-runtime.ts:955
function teamsConversationRouteStateKey(conversationId: string): string {
const baseConversationId = conversationId.replace(/;messageid=[^;]+/i, "");
return `teams:serviceUrl:conversation:${Buffer.from(baseConversationId).toString("base64url")}`;
}
const TEAMS_ACCEPTED_ACTIVITY_CACHE_TTL_MS = 30 * 24 * 60 * 60 * 1_000;
function normalizedTeamsServiceUrl(value: unknown): string {
if (typeof value !== "string" || value.length > 2048) {
throw new TeamsServiceUrlValidationError(
"Teams destination is missing its verified service URL",
);
}
let parsed: URL;
try {
parsed = new URL(value);
} catch {
throw new TeamsServiceUrlValidationError(
"Teams destination contains an invalid service URL",
);
}
if (
parsed.protocol !== "https:" ||
parsed.username ||
parsed.password ||
parsed.search ||
parsed.hash
) {
throw new TeamsServiceUrlValidationError(
"Teams destination contains an invalid service URL",
);
}
return parsed.toString().replace(/\/+$/, "");
}
function trustedTeamsServiceUrl(View on GitHub (pinned to 01ad858492)
Solutions
- Provide a fully-qualified absolute URL including scheme, e.g. https://smba.trafficmanager.net/.../.
- Fix the stored destination record so serviceUrl is the exact value from the Teams activity.
- Trim whitespace/control characters that may make the URL unparseable.
- Log and inspect the failing value to confirm whether the record was truncated or misconfigured.
Example fix
// before serviceUrl: "smba.trafficmanager.net/americas" // after serviceUrl: "https://smba.trafficmanager.net/americas"
Defensive patterns
Strategy: validation
Validate before calling
let parsed: URL;
try { parsed = new URL(dest.serviceUrl); } catch { throw new Error("serviceUrl is not an absolute URL"); } Type guard
function isAbsoluteUrl(value: string): boolean {
try { new URL(value); return true; } catch { return false; }
} Try / catch
try {
const url = normalizedTeamsServiceUrl(dest.serviceUrl);
} catch (e) {
if (e instanceof TeamsServiceUrlValidationError) {
// log the raw value and require the exact serviceUrl from the Teams activity
}
} Prevention
- Never hand-type serviceUrl values; copy them verbatim from the Bot Connector activity.
- Validate with new URL() before persisting destination rows.
- Trim whitespace/control characters from stored URLs.
- Reject hostname-only strings lacking a scheme at ingestion.
When it happens
Trigger: Calling the Teams destination normalization with a serviceUrl string such as 'not-a-url', 'localhost:3979/api/messages' without scheme prefix issues, or a garbled/truncated string that new URL(value) cannot parse.
Common situations: Hand-edited config where https:// was dropped; a truncated URL from a bad DB write; using a relative path or hostname-only value instead of an absolute URL.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- Teams destination is missing its verified service URL
- Teams destination contains an untrusted service URL
- devUiUrl must use http or https protocol
- Invalid published report URL
- decodeThreadId is unavailable
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/289deaeb15d74413.
Report an issue: GitHub.