can1357/oh-my-pi · error · Error

SARIF artifact URI must resolve to a repository file: ${uri}

Error message

SARIF artifact URI must resolve to a repository file: ${uri}

What it means

After resolving the artifact URI against the declared base, the importer requires the result to be a file: URL — SARIF locations must point at repository files, not http(s), data, or other schemes. Non-file URIs cannot be mapped to a repository path and are rejected.

Source

Thrown at packages/coding-agent/src/security/importers/sarif.ts:117

async function resolveSarifArtifactPath(
	artifact: SarifArtifactLocation,
	run: SarifRun,
	repositoryRoot: string,
): Promise<string> {
	const uri = artifact.uri;
	if (!uri) throw new Error("SARIF artifact location is missing its URI");
	const rootUrl = pathToFileURL(`${repositoryRoot}${path.sep}`);
	let baseUrl = rootUrl;
	if (artifact.uriBaseId) {
		const declaredBase = run.originalUriBaseIds?.[artifact.uriBaseId]?.uri;
		if (!declaredBase && artifact.uriBaseId !== "%SRCROOT%") {
			throw new Error(`SARIF artifact uses an unknown URI base: ${artifact.uriBaseId}`);
		}
		baseUrl = declaredBase ? new URL(declaredBase, rootUrl) : rootUrl;
	}
	const resolvedUrl = new URL(uri.replaceAll("\\", "/"), baseUrl);
	if (resolvedUrl.protocol !== "file:") {
		throw new Error(`SARIF artifact URI must resolve to a repository file: ${uri}`);
	}
	const absolute = path.resolve(fileURLToPath(resolvedUrl));
	if (!pathIsWithin(absolute, repositoryRoot)) {
		throw new Error(`SARIF artifact resolves outside the repository: ${uri}`);
	}
	const canonical = await fs.realpath(absolute).catch(error => {
		if (error instanceof Error && "code" in error && error.code === "ENOENT") return absolute;
		throw error;
	});
	if (!pathIsWithin(canonical, repositoryRoot)) {
		throw new Error(`SARIF artifact resolves outside the repository through a symbolic link: ${uri}`);
	}
	return path.relative(repositoryRoot, canonical).replaceAll(path.sep, "/");
}

async function normalizeSarifLocations(
	result: SarifResult,
	run: SarifRun,

View on GitHub (pinned to 9690622007)

Solutions

  1. Change the artifact uri to a relative path (e.g. "src/x.ts") so it resolves against the repository root file URL
  2. Replace http(s) originalUriBaseIds entries with file: URLs pointing inside the repository
  3. Strip absolute remote URIs and rewrite them as repository-relative paths before import

Example fix

// before
"uri": "https://ci.example.com/artifacts/src/x.ts"
// after
"uri": "src/x.ts"
Defensive patterns

Strategy: validation

Validate before calling

const resolved = new URL(artifactLocation.uri.replaceAll("\\", "/"), baseFileUrl);
if (resolved.protocol !== "file:") {
  throw new Error(`URI must resolve to a repository file, got ${resolved.protocol}`);
}

Type guard

function isFileUrl(u: URL): boolean {
  return u.protocol === "file:";
}

Try / catch

try {
  const bundle = await importSarif(sarifDir, repoRoot);
} catch (err) {
  if (err instanceof Error && err.message.startsWith("SARIF artifact URI must resolve to a repository file")) {
    console.error("Rewrite the URI to a repo-relative path or a file: base before importing");
  } else throw err;
}

Prevention

When it happens

Trigger: The artifact uri (possibly combined with an originalUriBaseIds base) resolves to a URL whose protocol is not file: — e.g. uri "https://example.com/x.ts" or a base declared as an http URL.

Common situations: SARIF from CI that uploads artifacts and references them by URL; originalUriBaseIds entries pointing at hosted locations; relative URI that resolves against an http base.

Related errors


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