ruvnet/ruflo · error · Error
memory path contains disallowed characters
Error message
memory path contains disallowed characters
What it means
Security guard inside resolveMemoryPath() (agenticow-loader.ts:72): the raw, pre-resolution path is tested against /\.\.[\\/]|\0/ and rejected. This is D-2 style hardening (the same rule the MCP verbs use) blocking path traversal ('../', '..\\') and NUL-byte injection before the path is joined onto the project cwd. Any '..' path segment with a following slash or backslash, anywhere in the string, is enough to trigger it.
Source
Thrown at v3/@claude-flow/cli/src/mcp-tools/agenticow-loader.ts:72
}
/** Reset the module-level load cache. Test-only seam. */
export function __resetAgenticowCache(): void {
_agenticowMod = null;
_loadAttempted = false;
}
export function degradedResult(reason: string): { success: true; degraded: true; reason: string } {
return { success: true, degraded: true, reason };
}
/**
* Resolve a user-supplied memory path against the project cwd, rejecting path
* traversal and NUL bytes (D-2 style hardening — same rule the MCP verbs use).
*/
export function resolveMemoryPath(path: string): string {
if (!path || typeof path !== 'string') throw new Error('memory path is required');
if (/\.\.[\\/]|\0/.test(path)) throw new Error('memory path contains disallowed characters');
return isAbsolute(path) ? path : resolve(getProjectCwd(), path);
}
/**
* Lineage manifest companion path. agenticow persists the COW chain
* (working → checkpoints → base) into `<file>.agenticow.json` next to the
* `.rvf` data file. Without it, forks/checkpoints are in-memory only and
* disappear when the AgenticMemory handle closes.
*/
export function manifestFor(file: string): string {
return `${file}.agenticow.json`;
}
/** Validate a COW branch/checkpoint label (alnum + a small safe symbol set). */
export function validateLabel(label: string): string {
if (!label || typeof label !== 'string') throw new Error('label is required');
if (label.length > 256) throw new Error('label exceeds 256 chars');
if (!/^[A-Za-z0-9_.\-:/@]+$/.test(label)) {View on GitHub (pinned to fa13ee4ad6)
Solutions
- Restructure so the memory file lives under the project cwd and reference it with a plain relative path containing no '..' segments
- Pass an absolute path when the file genuinely lives outside the project cwd
- Sanitize incoming paths yourself (reject '..' segments and NUL) before forwarding them to the tool
Example fix
// before
await callTool('agenticow_ingest', {
path: '../shared/vectors.rvf', // throws: disallowed characters
records: [{ vector: [0.1] }],
});
// after
await callTool('agenticow_ingest', {
path: '/srv/shared/vectors.rvf', // absolute path, no '..' segment
records: [{ vector: [0.1] }],
}); Defensive patterns
Strategy: validation
Validate before calling
function isSafeMemoryPath(p: string): boolean {
return !/\.\.[\\/]|\0/.test(p); // same rule as resolveMemoryPath
}
if (!isSafeMemoryPath(userPath)) throw new TypeError('path must not contain .. or NUL'); Try / catch
try {
await callTool('agenticow_ingest', args);
} catch (e) {
if (e instanceof Error && e.message.includes('disallowed characters')) {
return { error: 'bad_request', detail: 'reject path traversal in memory path' };
}
throw e;
} Prevention
- Build memory paths with path.join from an allow-listed base directory instead of concatenating raw input
- Reject '..' segments at your API boundary before anything reaches the MCP tool
- Treat repeated triggers from external input as reconnaissance and rate-limit the caller
When it happens
Trigger: Any agenticow_* tool call whose path contains a parent-directory segment anywhere — '../../etc/passwd', 'data/../../secrets.rvf', '..\\win\\mem.rvf' — or an embedded NUL byte ('\0'). Because the check runs on the raw string before resolve(), even a benign interior segment like 'a/../b' is rejected, not just leading traversal.
Common situations: Paths built by concatenating user input; normalizing paths that legitimately cross directories ('../shared/memory.rvf'); templates that emit relative paths rooted outside the project; adversarial probes against an exposed MCP endpoint.
Related errors
- Key contains disallowed characters
- Namespace contains disallowed characters
- namespace contains disallowed characters
- namespace contains path traversal
- unknown strategy "${name}". Available: ${roster.map((r) => r
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/7592baeda98207e9.
Report an issue: GitHub.