can1357/oh-my-pi · error

rule:// URL requires a rule name: rule://<name>

Error message

rule:// URL requires a rule name: rule://<name>

What it means

The rule:// protocol resolves an active rule by name taken from url.rawHost || url.hostname. If the URL has no host component (e.g. bare 'rule://'), there is no rule name to look up and resolve() throws this usage error stating the expected form rule://<name>.

Source

Thrown at packages/coding-agent/src/internal-urls/rule-protocol.ts:19

/**
 * Protocol handler for rule:// URLs.
 *
 * URL forms:
 * - rule://<name> - Reads rule content
 */
import { getActiveRules } from "../capability/rule";
import type { InternalResource, InternalUrl, ProtocolHandler, UrlCompletion } from "./types";

export class RuleProtocolHandler implements ProtocolHandler {
	readonly scheme = "rule";
	readonly immutable = true;

	async resolve(url: InternalUrl): Promise<InternalResource> {
		const rules = getActiveRules();

		const ruleName = url.rawHost || url.hostname;
		if (!ruleName) {
			throw new Error("rule:// URL requires a rule name: rule://<name>");
		}

		const rule = rules.find(r => r.name === ruleName);
		if (!rule) {
			const available = rules.map(r => r.name);
			const availableStr = available.length > 0 ? available.join(", ") : "none";
			throw new Error(`Unknown rule: ${ruleName}\nAvailable: ${availableStr}`);
		}

		return {
			url: url.href,
			content: rule.content,
			contentType: "text/markdown",
			size: Buffer.byteLength(rule.content, "utf-8"),
			sourcePath: rule.path,
			notes: [],
		};
	}

View on GitHub (pinned to 9690622007)

Solutions

  1. Include the rule name in the URL: rule://my-rule-name.
  2. List available rule names first (getActiveRules() or the rule listing mechanism) and use one exactly.
  3. Guard template construction so empty rule names never produce a bare rule:// URL.

Example fix

// before
const url = `rule://${ruleName}`;
// after
if (!ruleName) throw new Error('rule name required');
const url = `rule://${encodeURIComponent(ruleName)}`;
Defensive patterns

Strategy: validation

Validate before calling

if (!ruleName) throw new Error('rule:// URL requires a rule name: rule://<name>');
const url = `rule://${encodeURIComponent(ruleName)}`;

Type guard

const isValidRuleUrl = (u: string): boolean => /^rule:\/\/.+/i.test(u);

Try / catch

try {
  return await router.resolve(url);
} catch (err) {
  if (err instanceof Error && err.message.includes('requires a rule name')) throw new Error('supply rule://<name> with a non-empty rule name');
  throw err;
}

Prevention

When it happens

Trigger: Resolving 'rule://' with an empty host/hostname — missing the rule name segment entirely.

Common situations: Constructing the URL by string concatenation where the name variable was empty; completion/browse flows hitting the bare namespace URL.

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


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