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
- Provide a non-empty scheme string on every entry passed to setSchemes
- Trim user input and reject empty values before calling setSchemes
- Fix the config/source supplying the definitions (missing or blank scheme key)
- 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
- Always require and trim the scheme field in config parsing
- Reject blank scheme entries at config-load time with a clear message
- Type definitions so scheme is a required non-empty string
- Add a unit test covering missing/blank scheme input
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
- Host URI scheme contains invalid characters: ${raw.scheme}
- Host URI scheme is reserved by OMP: ${scheme}://
- Unsupported language '{value}'. Supported: {}
- Unable to infer language from file extension: {}. Specify `l
- Invalid pattern: {err}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/b0e133bcf5723fa9.
Report an issue: GitHub.