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
- Make the path relative to the canonical repository root before publishing (strip the root prefix with path.relative)
- Remove any '..' traversal segments by resolving and re-relativizing the path
- Reject/fix empty or whitespace-only path strings at the finding source
- 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
- Store repo-relative paths only
- path.relative() from repo root at creation time
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
- Provider delete URL must not embed an account credential
- Destination paths cannot contain parent traversal or NUL byt
- Upload filename is invalid
- Shared-folder destination escapes its configured root
- Absolute paths are not allowed in ${scheme}:// URLs: ${rawPa
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/7f9c1bd128aa56e3.
Report an issue: GitHub.