can1357/oh-my-pi · error · Error

Host URI scheme must be a non-empty string

Error message

Host URI scheme must be a non-empty string

What it means

RpcHostUriSchemes.setSchemes validates each registered host URI scheme definition and throws when the scheme field is missing, not a string, or empty/whitespace after trimming/lowercasing. Schemes are the foundation of host:// URIs, so an unusable scheme name is rejected up front.

Source

Thrown at packages/coding-agent/src/modes/rpc/host-uris.ts:95

		this.#output = output;
		this.#router = router;
	}

	getSchemes(): string[] {
		return Array.from(this.#definitions.keys());
	}

	/**
	 * Replace the registered set of host URI schemes. Previously registered
	 * schemes that no longer appear in the new set are unregistered from the
	 * router; surviving and new schemes get fresh handler instances.
	 */
	setSchemes(schemes: RpcHostUriSchemeDefinition[]): string[] {
		const normalized = new Map<string, RpcHostUriSchemeDefinition>();
		for (const raw of schemes) {
			const scheme = typeof raw?.scheme === "string" ? raw.scheme.trim().toLowerCase() : "";
			if (!scheme) {
				throw new Error("Host URI scheme must be a non-empty string");
			}
			if (!/^[a-z][a-z0-9+.-]*$/.test(scheme)) {
				throw new Error(`Host URI scheme contains invalid characters: ${raw.scheme}`);
			}
			if (RESERVED_HOST_URI_SCHEMES.has(scheme)) {
				throw new Error(`Host URI scheme is reserved by OMP: ${scheme}://`);
			}
			normalized.set(scheme, {
				scheme,
				description: typeof raw.description === "string" ? raw.description : undefined,
				writable: raw.writable === true,
				immutable: raw.immutable === true,
			});
		}

		for (const previous of this.#definitions.keys()) {
			if (!normalized.has(previous)) {
				this.#router.unregister(previous);

View on GitHub (pinned to 9690622007)

Solutions

  1. Provide a non-empty scheme string on every entry passed to setSchemes
  2. Trim user input and reject empty values before calling setSchemes
  3. Fix the config/source supplying the definitions (missing or blank scheme key)
  4. Validate entries against RpcHostUriSchemeDefinition (scheme: required string) before registration

Example fix

// before
setSchemes([{ scheme: "", description: "docs" }]);
// after
setSchemes([{ scheme: "docs", description: "docs" }]);
Defensive patterns

Strategy: validation

Validate before calling

function isValidSchemeEntry(raw) {
  return typeof raw?.scheme === "string" && raw.scheme.trim().length > 0;
}
setSchemes(defs.filter(isValidSchemeEntry));

Type guard

function hasScheme(raw: unknown): raw is { scheme: string } {
  return typeof (raw as { scheme?: unknown })?.scheme === "string" && (raw as { scheme: string }).scheme.trim() !== "";
}

Try / catch

try {
  hostUris.setSchemes(defs);
} catch (err) {
  if (err.message === "Host URI scheme must be a non-empty string") {
    logger.warn("Dropping scheme entries with empty/missing scheme", { count: defs.length });
  } else throw err;
}

Prevention

When it happens

Trigger: Calling setSchemes with an entry whose .scheme is undefined/null/non-string, or an empty string or only whitespace (e.g. { scheme: "", description: ... }).

Common situations: Config file with a scheme entry missing the key or set to ""; programmatic registration passing a malformed object; deserialized JSON where the scheme field was dropped.

Related errors


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