can1357/oh-my-pi · error · Error

Security remediation requires at least one finding id

Error message

Security remediation requires at least one finding id

What it means

prepareSecurityRemediationWorkspace deduplicates, trims and filters the request.findingIds list; if nothing remains it throws, since a remediation workspace without target findings has nothing to do. The request is rejected before any isolation context is prepared.

Source

Thrown at packages/coding-agent/src/security/remediation.ts:70

}

export function assertSecurityRemediationBaselineClean(baseline: WorktreeBaseline): void {
	const dirty = repoBaselineDirty(baseline);
	if (dirty.length === 0) return;
	throw new Error(
		[
			`Security remediation refuses a dirty working tree (${dirty.join(", ")}).`,
			"Commit or stash the changes before creating an isolated remediation workspace.",
		].join(" "),
	);
}

export async function prepareSecurityRemediationWorkspace(
	request: SecurityRemediationRequest,
	dependencies: SecurityRemediationDependencies = {},
): Promise<SecurityRemediationWorkspace> {
	const findingIds = [...new Set(request.findingIds.map(id => id.trim()).filter(Boolean))];
	if (findingIds.length === 0) throw new Error("Security remediation requires at least one finding id");
	const prepareContext = dependencies.prepareContext ?? prepareIsolationContext;
	const createIsolation = dependencies.createIsolation ?? ensureIsolation;
	const disposeIsolation = dependencies.cleanupIsolation ?? cleanupIsolation;
	const context = await prepareContext(request.cwd);
	assertSecurityRemediationBaselineClean(context.baseline);
	const id = request.isolationId?.trim() || dependencies.createId?.() || createRemediationId();
	const handle = await createIsolation(context.repoRoot, id, request.preferredBackend);
	let cleaned = false;
	return {
		id,
		repositoryRoot: context.repoRoot,
		worktreePath: handle.mergedDir,
		findingIds,
		backend: handle.backend,
		fellBack: handle.fellBack,
		fallbackReason: handle.fallbackReason,
		async cleanup() {
			if (cleaned) return;

View on GitHub (pinned to 9690622007)

Solutions

  1. Pass at least one valid finding id, e.g. findingIds: ['secscan_...-fp3']
  2. Take the ids from the published scan's findings (fingerprint ids) rather than free-form strings
  3. Validate the list is non-empty at the call site before constructing the request

Example fix

// before
await prepareSecurityRemediationWorkspace({ cwd, findingIds: [] });
// after
await prepareSecurityRemediationWorkspace({ cwd, findingIds: [publishedFinding.fingerprint] });
Defensive patterns

Strategy: validation

Validate before calling

if (!request.findingIds.some(id => id.trim())) throw new Error("findingIds required");

Type guard

null

Try / catch

try { await prepare(request); } catch (e) { if (String(e.message).includes("at least one finding id")) { /* ask caller for ids */ } else throw e; }

Prevention

When it happens

Trigger: Calling prepareSecurityRemediationWorkspace (or the workspace entry) with findingIds: [], or an array whose entries are all empty/whitespace strings after trim (e.g. [' ', '']).

Common situations: An agent passes the raw findings array field without ids, upstream parsing dropped malformed ids, a template/default request was sent without filling findingIds, or ids were consumed/filtered in earlier processing.

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


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