can1357/oh-my-pi · error · Error
OAuth resource URI must not include a fragment
Error message
OAuth resource URI must not include a fragment
What it means
RFC 8707 resource indicators must not contain a fragment; the resource is an audience identifier for the token, and a fragment would either break the provider's exact-match comparison or leak path data. resolveResourceUri parses the trimmed URL and rejects it if the URL has a hash fragment.
Source
Thrown at packages/coding-agent/src/mcp/oauth-flow.ts:256
callbackHostname: resolveCallbackHostname(redirectUri),
redirectUri,
allowPortFallback,
};
}
function resolveResourceUri(resource: string | undefined): string | undefined {
const trimmed = resource?.trim();
if (!trimmed) return undefined;
if (trimmed !== resource) {
throw new Error("OAuth resource URI must not include surrounding whitespace");
}
const parsed = new URL(trimmed);
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
throw new Error("OAuth resource URI must use http or https");
}
if (parsed.hash) {
throw new Error("OAuth resource URI must not include a fragment");
}
return trimmed;
}
interface ResourceIndicatorFilterOptions {
/** Strip any resource URL on the same origin as the authorization server. */
stripSameOriginResource?: boolean;
}
/**
* Drop a redundant fallback resource indicator relative to {@link serverUrl}.
*
* Provider-advertised resource indicators are authoritative even when they are
* origin-only (`https://gateway.example.com`) or path-scoped same-origin
* (`https://gateway.example.com/my-service/mcp`): servers can use either form
* as the audience they require for the grant.
*
* Plane is stricter for OMP-synthesized fallback resources (e.g. using theView on GitHub (pinned to 9690622007)
Solutions
- Strip the #fragment from the configured resource URI
- Use only scheme://host/path?query form — typically just the origin or base path of the MCP server
- When copying URLs from a browser, remove any anchor portion before pasting into config
Example fix
// before "resource": "https://acme.example/mcp#tools" // after "resource": "https://acme.example/mcp"
Defensive patterns
Strategy: validation
Validate before calling
const res = config.oauth?.resource;
if (res != null && new URL(res.trim()).hash) {
throw new Error(`resource must not contain a fragment: '${res}'`);
} Type guard
function isFragmentFreeUrl(s) {
try { return !new URL(s).hash; } catch { return false; }
} Try / catch
try {
startOAuthFlow(config);
} catch (e) {
if (e.message.includes('must not include a fragment')) {
const u = new URL(config.oauth.resource);
config.oauth.resource = u.origin + u.pathname;
startOAuthFlow(config);
} else throw e;
} Prevention
- Never paste URLs with #anchor portions from a browser into resource config
- Use only scheme://host/path form for resource indicators
- Strip fragments programmatically when deriving the resource from a page URL
When it happens
Trigger: Configuring the OAuth resource option with a trailing fragment, e.g. "https://acme.example/mcp#section" or a URL pasted from a browser that included an anchor, then constructing the flow options or accessing resolvedResource.
Common situations: Copying the MCP server URL straight from a browser address bar where a page anchor was present; template-generated URLs appending #fragment; confusion between resource indicators and web page URLs.
Related errors
- OAuth redirect URI must not include surrounding whitespace
- OAuth redirect URI must use http or https
- OAuth resource URI must not include surrounding whitespace
- OAuth resource URI must use http or https
- OMP_AUTH_BROKER_ACCOUNT_POOL_FILE contains an empty provider
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/724a066e0ef9d360.
Report an issue: GitHub.