affaan-m/ECC · error · Error
seedPaths entries must stay inside repoRoot
Error message
seedPaths entries must stay inside repoRoot: ${entry} What it means
normalizeSeedPaths resolves each seed path against the repo root and rejects entries that escape it (relative path starting with '..' or resolving to an absolute path outside the root). This is a path-traversal guard ensuring seed data can only be copied from within the repository.
Solutions
- Change the entry to a path relative to and inside repoRoot (e.g. 'skills/foo', 'scripts/lib').
- Copy the needed files into the repo first, then reference them via seedPaths.
- If the source must live outside, move it into the repo or create a symlink inside the repo that resolves within the root.
- Check for symlinks resolving outside the root and re-point them within the repo.
Example fix
// before seedPaths: ['../shared/skills'] // after seedPaths: ['skills'] // after copying shared skills into the repo
Defensive patterns
Strategy: validation
Validate before calling
const path = require('path');
function isInsideRepo(repoRoot, entry) {
const rel = path.relative(path.resolve(repoRoot), path.resolve(repoRoot, entry));
return rel !== '' && !rel.startsWith('..') && !path.isAbsolute(rel);
} Type guard
const safeSeedEntry = (e, root) => typeof e === 'string' && e.length > 0 && !path.relative(path.resolve(root), path.resolve(root, e)).startsWith('..') && !path.isAbsolute(path.relative(path.resolve(root), path.resolve(root, e))); Try / catch
try {
const seeds = normalizeSeedPaths(repoRoot, entries);
} catch (e) {
if (String(e.message).startsWith('seedPaths entries must stay inside repoRoot')) {
console.error('Offending entry:', e.message.split(': ').pop());
}
throw e;
} Prevention
- Store seed paths as repo-relative paths only.
- Avoid symlinks that point outside the repository.
- Validate seed paths in CI against path.relative checks.
- Never accept absolute paths or '..' segments in seed config.
When it happens
Trigger: Passing seedPaths entries like '../shared/config' or absolute paths outside the repo (e.g. '/etc/passwd'); symlinks whose resolution lands outside repoRoot; a config with OS-specific paths built on a different machine.
Common situations: Reusing a seed-paths config across repos where the referenced sibling directory lives outside the current root; attempts to seed from a global folder; symlinked entries in config pointing to a home directory.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
- artifact path escapes output directory
- artifact path must stay beneath output root
- buildOrchestrationPlan requires at least one worker
- launcherCommand must be a non-empty string
- memory id must match mem_<lowercase-id> and cannot contain…
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/41dfcf7a15bfb04e.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/tmux-worktree-orchestrator.js:71
function normalizeSeedPaths(seedPaths, repoRoot) {
const resolvedRepoRoot = path.resolve(repoRoot);
const entries = Array.isArray(seedPaths) ? seedPaths : [];
const seen = new Set();
const normalized = [];
for (const entry of entries) {
if (typeof entry !== 'string' || entry.trim().length === 0) {
continue;
}
const absolutePath = path.resolve(resolvedRepoRoot, entry);
const relativePath = path.relative(resolvedRepoRoot, absolutePath);
if (
relativePath.startsWith('..') ||
path.isAbsolute(relativePath)
) {
throw new Error(`seedPaths entries must stay inside repoRoot: ${entry}`);
}
const normalizedPath = relativePath.split(path.sep).join('/');
if (seen.has(normalizedPath)) {
continue;
}
seen.add(normalizedPath);
normalized.push(normalizedPath);
}
return normalized;
}
function overlaySeedPaths({ repoRoot, seedPaths, worktreePath }) {
const normalizedSeedPaths = normalizeSeedPaths(seedPaths, repoRoot);
for (const seedPath of normalizedSeedPaths) {View on GitHub (pinned to 8321021c54)