can1357/oh-my-pi · error
Daemon name must be 1-48 letters, numbers, dots, underscores
Error message
Daemon name must be 1-48 letters, numbers, dots, underscores, or hyphens
What it means
DaemonBroker.#start validates the daemon name against /^[A-Za-z0-9][A-Za-z0-9._-]{0,47}$/ before creating anything: the name must be 1-48 chars, start with a letter or digit, and use only letters, digits, dots, underscores, hyphens. This guards downstream use of the name in process management, file paths, and subscription keys from path/lookup injection or collisions.
Source
Thrown at packages/coding-agent/src/launch/broker.ts:598
const record = this.#record(operation.name);
await this.#stopRecord(record, operation.timeoutMs);
return { op: "stop", daemon: record.snapshot };
}
case "restart":
return this.#restart(operation.name);
case "describe": {
const record = this.#record(operation.name);
await this.#refreshDetached(record);
return { op: "describe", daemon: record.snapshot, spec: record.spec };
}
case "shutdown":
return { op: "shutdown" };
}
}
async #start(spec: DaemonSpec, owner?: string): Promise<DaemonRpcResult> {
if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,47}$/.test(spec.name)) {
throw new Error("Daemon name must be 1-48 letters, numbers, dots, underscores, or hyphens");
}
if (spec.detached && spec.pty) {
throw new Error("A detached daemon cannot allocate a PTY");
}
if (
spec.pty &&
process.platform === "win32" &&
[".bat", ".cmd"].includes(path.extname(spec.application).toLowerCase())
) {
throw new Error('Windows batch files require application "cmd.exe" with the batch path after "/c"');
}
if (this.#startingNames.has(spec.name)) {
throw new Error(`Daemon ${spec.name} is already starting`);
}
this.#startingNames.add(spec.name);
let record: ManagedDaemon;
try {
const existing = this.#records.get(spec.name);View on GitHub (pinned to 9690622007)
Solutions
- Rename the daemon to a 1-48 char string matching [A-Za-z0-9][A-Za-z0-9._-]* (must start with alphanumeric)
- Sanitize derived names: strip/replace invalid characters and truncate to 48 chars, prefixing with an alphanumeric if needed
- Validate the name client-side with the same regex before issuing the start request
Example fix
// before
await broker.start({ name: `daemon for ${projectPath}` }); // spaces and slashes -> throws
// after
const safe = projectPath.replace(/[^A-Za-z0-9._-]+/g, '-').replace(/^[._-]+/, '').slice(0, 48) || 'daemon';
await broker.start({ name: safe }); Defensive patterns
Strategy: validation
Validate before calling
const DAEMON_NAME_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,47}$/;
function isValidDaemonName(name: string): boolean { return DAEMON_NAME_RE.test(name); }
if (!isValidDaemonName(spec.name)) throw new Error(`Invalid daemon name: ${spec.name}`); Try / catch
try {
await broker.start(spec);
} catch (err) {
if (err instanceof Error && err.message.startsWith('Daemon name must be')) {
return broker.start({ ...spec, name: sanitizeDaemonName(spec.name) });
}
throw err;
} Prevention
- Centralize a sanitizeDaemonName helper (replace [^A-Za-z0-9._-], strip leading dots/dashes, cap at 48 chars) and use it wherever names are derived
- Never pass raw user input, paths, or branch names as daemon names
- Add a form/UI-level validator mirroring the broker regex
- Keep derived names short — appending suffixes can silently exceed the 48-char cap
When it happens
Trigger: Calling the broker's start/startDaemon RPC (via #start) with a name that is empty, longer than 48 chars, starts with '.', '_' or '-', or contains characters like spaces, slashes, '@', or unicode.
Common situations: Deriving daemon names from user input, project paths, or branch names that contain slashes or spaces; generating names via templating that yields empty strings; suffixing IDs to names and exceeding the 48-char limit; localized/unicode names from non-ASCII project titles.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- Invalid skill name "${raw}". Use lowercase letters, digits,
- Unknown tool${unknown.length === 1 ? "" : "s"} in --tools: $
- Unknown OAuth provider '${providerArg}'. Known: ${providers
- Invalid package name: ${name}
- Invalid package name: ${name}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/2b61b9fce402f46c.
Report an issue: GitHub.