diegosouzapw/OmniRoute · error · Error
Invalid profile identifier
Error message
Invalid profile identifier
What it means
Sentinel from safePathSegment: after stripping characters outside [a-zA-Z0-9._-] (replaced with _) and truncating to 120 chars, the input collapsed to an empty string, ".", or "..". The value at fault is the VNC profile name input — either the connectionId (persistProfiles mode) or the sessionId used to name the profile directory under VNC_CONFIG.profileDir. A path-traversal/empty-name guard, not a runtime state error.
Solutions
- Inspect the connectionId/sessionId passed into createProfileDir — it must contain at least one safe character
- Reject or regenerate caller-supplied identifiers that sanitize to nothing
- Never bypass the guard: it prevents writing profiles outside the profile root
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at src/lib/vncSession/service.ts:127 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of diegosouzapw/OmniRoute@a179ffed5b (2026-08-25).
Data as JSON: /api/errors/cc4b771b3f4df3f7.
Report an issue: GitHub.
Appendix: source
Thrown at src/lib/vncSession/service.ts:127
if (ids.length > 0) {
await docker(["rm", "-f", ...ids], { timeoutMs: 30_000 });
}
})();
}
await reconciliationPromise;
}
function findActiveSessionForConnection(connectionId: string): VncSession | undefined {
return [...SESSIONS.values()].find(
(session) =>
session.connectionId === connectionId &&
["starting", "running", "harvesting"].includes(session.status)
);
}
function safePathSegment(value: string): string {
const safe = value.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 120);
if (!safe || safe === "." || safe === "..") throw new Error("Invalid profile identifier");
return safe;
}
function createProfileDir(connectionId: string, sessionId: string): string {
mkdirSync(VNC_CONFIG.profileDir, { recursive: true, mode: 0o700 });
chmodSync(VNC_CONFIG.profileDir, 0o700);
const profileName = safePathSegment(VNC_CONFIG.persistProfiles ? connectionId : sessionId);
const profileDir = join(VNC_CONFIG.profileDir, profileName);
mkdirSync(profileDir, { recursive: true, mode: 0o700 });
chmodSync(profileDir, 0o700);
return profileDir;
}
async function publishedPort(containerName: string, containerPort: number): Promise<number> {
const result = await docker(["port", containerName, `${containerPort}/tcp`], {
timeoutMs: 10_000,
});
if (result.code !== 0) {View on GitHub (pinned to a179ffed5b)