can1357/oh-my-pi · error · Error

OAuth resource URI must not include surrounding whitespace

Error message

OAuth resource URI must not include surrounding whitespace

What it means

resolveResourceUri validates the RFC 8707 resource indicator used in the MCP OAuth flow. It trims the value to test presence, and if trimming changed the value the configured resource URI has surrounding whitespace. A whitespace-padded resource would not match the provider's registered resource indicator, breaking token audience binding, so it is rejected early.

Source

Thrown at packages/coding-agent/src/mcp/oauth-flow.ts:248

	// registration on demand with whichever loopback URI we actually bound —
	// the provider issues a client_id tied to *that* URI, so the random-port
	// fallback remains safe for first-install DCR flows whose preferred port
	// happens to be occupied.
	const allowPortFallback = staticClientIdFromConfig(config) === undefined;
	return {
		preferredPort: resolveCallbackPort(config.callbackPort, redirectUri),
		callbackPath: resolveCallbackPath(config.callbackPath, redirectUri),
		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;
}

/**

View on GitHub (pinned to 9690622007)

Solutions

  1. Remove surrounding whitespace from the configured resource URI
  2. Trim the value at config-load time or at the source (env var export, template) before passing it to the OAuth options
  3. Add config validation that rejects resource values differing from their trimmed form

Example fix

// before
"resource": " https://acme.example/mcp "
// after
"resource": "https://acme.example/mcp"
Defensive patterns

Strategy: validation

Validate before calling

const res = config.oauth?.resource;
if (res != null && res.trim() !== res) {
  throw new Error(`resource has surrounding whitespace: ${JSON.stringify(res)}`);
}

Try / catch

try {
  startOAuthFlow(config);
} catch (e) {
  if (e.message.includes('resource URI must not include surrounding whitespace')) {
    config.oauth.resource = config.oauth.resource.trim();
    startOAuthFlow(config);
  } else throw e;
}

Prevention

When it happens

Trigger: Configuring the OAuth resource option with leading/trailing spaces (copy-paste artifacts, env var with trailing newline, YAML/JSON padding) and then constructing the OAuth flow options (constructor) or accessing filtered/resolvedResource.

Common situations: Pasting the MCP server URL from documentation with a trailing space; environment variables that swallowed a newline; generated configs that concatenate strings with stray spaces.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/35c255cda0fa7122. Report an issue: GitHub.