{"record":{"id":"7712dc90d3dda8b1","repo":"can1357/oh-my-pi","slug":"security-remediation-requires-at-least-one-finding","errorCode":null,"errorMessage":"Security remediation requires at least one finding id","messagePattern":"Security remediation requires at least one finding id","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/security/remediation.ts","lineNumber":70,"sourceCode":"}\n\nexport function assertSecurityRemediationBaselineClean(baseline: WorktreeBaseline): void {\n\tconst dirty = repoBaselineDirty(baseline);\n\tif (dirty.length === 0) return;\n\tthrow new Error(\n\t\t[\n\t\t\t`Security remediation refuses a dirty working tree (${dirty.join(\", \")}).`,\n\t\t\t\"Commit or stash the changes before creating an isolated remediation workspace.\",\n\t\t].join(\" \"),\n\t);\n}\n\nexport async function prepareSecurityRemediationWorkspace(\n\trequest: SecurityRemediationRequest,\n\tdependencies: SecurityRemediationDependencies = {},\n): Promise<SecurityRemediationWorkspace> {\n\tconst findingIds = [...new Set(request.findingIds.map(id => id.trim()).filter(Boolean))];\n\tif (findingIds.length === 0) throw new Error(\"Security remediation requires at least one finding id\");\n\tconst prepareContext = dependencies.prepareContext ?? prepareIsolationContext;\n\tconst createIsolation = dependencies.createIsolation ?? ensureIsolation;\n\tconst disposeIsolation = dependencies.cleanupIsolation ?? cleanupIsolation;\n\tconst context = await prepareContext(request.cwd);\n\tassertSecurityRemediationBaselineClean(context.baseline);\n\tconst id = request.isolationId?.trim() || dependencies.createId?.() || createRemediationId();\n\tconst handle = await createIsolation(context.repoRoot, id, request.preferredBackend);\n\tlet cleaned = false;\n\treturn {\n\t\tid,\n\t\trepositoryRoot: context.repoRoot,\n\t\tworktreePath: handle.mergedDir,\n\t\tfindingIds,\n\t\tbackend: handle.backend,\n\t\tfellBack: handle.fellBack,\n\t\tfallbackReason: handle.fallbackReason,\n\t\tasync cleanup() {\n\t\t\tif (cleaned) return;","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/security/remediation.ts#L52-L88","documentation":"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.","triggerScenarios":"Calling prepareSecurityRemediationWorkspace (or the workspace entry) with findingIds: [], or an array whose entries are all empty/whitespace strings after trim (e.g. [' ', '']).","commonSituations":"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.","solutions":["Pass at least one valid finding id, e.g. findingIds: ['secscan_...-fp3']","Take the ids from the published scan's findings (fingerprint ids) rather than free-form strings","Validate the list is non-empty at the call site before constructing the request"],"exampleFix":"// before\nawait prepareSecurityRemediationWorkspace({ cwd, findingIds: [] });\n// after\nawait prepareSecurityRemediationWorkspace({ cwd, findingIds: [publishedFinding.fingerprint] });","handlingStrategy":"validation","validationCode":"if (!request.findingIds.some(id => id.trim())) throw new Error(\"findingIds required\");","typeGuard":"null","tryCatchPattern":"try { await prepare(request); } catch (e) { if (String(e.message).includes(\"at least one finding id\")) { /* ask caller for ids */ } else throw e; }","preventionTips":["Validate ids non-empty at boundary","Use ids from published findings"],"tags":["validation","input","security"],"backgroundTag":"missing-required-parameter","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}