can1357/oh-my-pi · error · Error

Security finding paths must be repository-relative: ${input}

Error message

Security finding paths must be repository-relative: ${input}

What it means

normalizePublishedPath validates every finding location path before persisting a security publication. A path must be non-empty, repository-relative (no leading '/', no Windows drive prefix, no '..' segments). Absolute or escaping paths would break the repository-relative contract of stored findings and could point outside the project.

Source

Thrown at packages/coding-agent/src/security/publication.ts:108

	plan: SecurityScanPlan;
	scanId: string;
	store: SecurityStore;
	startedAt: string;
	sessionId?: string;
	operationId?: string;
	onPublished?: (bundle: SecurityScanBundle) => void | Promise<void>;
}

function normalizePublishedPath(input: string): string {
	const normalized = input.replaceAll("\\", "/").replace(/^\.\//, "");
	const segments = normalized.split("/");
	if (
		!normalized ||
		normalized.startsWith("/") ||
		/^[a-zA-Z]:\//.test(normalized) ||
		segments.some(segment => segment === "..")
	) {
		throw new Error(`Security finding paths must be repository-relative: ${input}`);
	}
	return normalized;
}

function toLocation(
	input: SecurityPublishParams["findings"][number]["locations"][number],
	plan: SecurityScanPlan,
): SecurityLocation {
	const normalizedPath = normalizePublishedPath(input.path);
	if (!pathMatchesSecurityScope(normalizedPath, plan.target.includePaths, plan.target.excludePaths)) {
		throw new Error(`Security finding path is outside the immutable scan scope: ${input.path}`);
	}
	const location: SecurityLocation = {
		path: normalizedPath,
		startLine: input.start_line,
	};
	if (input.end_line !== undefined) location.endLine = input.end_line;
	if (input.start_column !== undefined) location.startColumn = input.start_column;

View on GitHub (pinned to 9690622007)

Solutions

  1. Make the path relative to the canonical repository root before publishing (strip the root prefix with path.relative)
  2. Remove any '..' traversal segments by resolving and re-relativizing the path
  3. Reject/fix empty or whitespace-only path strings at the finding source
  4. Normalize Windows drive-letter paths to the in-repo relative form

Example fix

// before
locations: [{ path: "/home/me/project/src/app.ts", start_line: 10 }]
// after
locations: [{ path: path.relative(repoRoot, "/home/me/project/src/app.ts"), start_line: 10 }] // "src/app.ts"
Defensive patterns

Strategy: validation

Validate before calling

if (!p || p.startsWith("/") || /^[a-zA-Z]:\//.test(p) || p.split("/").includes("..")) throw new Error("bad path");

Type guard

null

Try / catch

try { await publish(params); } catch (e) { if (String(e.message).includes("repository-relative")) { /* relativize and retry once */ } else throw e; }

Prevention

When it happens

Trigger: Publishing findings (SecurityPublishTool execute -> toLocation -> normalizePublishedPath) where input.path is absolute like '/src/app.ts', a Windows path 'C:/src/app.ts', contains '..' segments, or is empty/whitespace.

Common situations: LLM-generated findings carrying absolute paths read from the filesystem, mixing Windows-style scan output into a POSIX publication, or constructing location paths by concatenating the repo root with the relative path.

Related errors


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