{"record":{"id":"8343ef29b551f5e9","repo":"can1357/oh-my-pi","slug":"security-finding-path-is-outside-the-immutable-sca","errorCode":null,"errorMessage":"Security finding path is outside the immutable scan scope: ${input.path}","messagePattern":"Security finding path is outside the immutable scan scope: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/security/publication.ts","lineNumber":119,"sourceCode":"\tconst segments = normalized.split(\"/\");\n\tif (\n\t\t!normalized ||\n\t\tnormalized.startsWith(\"/\") ||\n\t\t/^[a-zA-Z]:\\//.test(normalized) ||\n\t\tsegments.some(segment => segment === \"..\")\n\t) {\n\t\tthrow new Error(`Security finding paths must be repository-relative: ${input}`);\n\t}\n\treturn normalized;\n}\n\nfunction toLocation(\n\tinput: SecurityPublishParams[\"findings\"][number][\"locations\"][number],\n\tplan: SecurityScanPlan,\n): SecurityLocation {\n\tconst normalizedPath = normalizePublishedPath(input.path);\n\tif (!pathMatchesSecurityScope(normalizedPath, plan.target.includePaths, plan.target.excludePaths)) {\n\t\tthrow new Error(`Security finding path is outside the immutable scan scope: ${input.path}`);\n\t}\n\tconst location: SecurityLocation = {\n\t\tpath: normalizedPath,\n\t\tstartLine: input.start_line,\n\t};\n\tif (input.end_line !== undefined) location.endLine = input.end_line;\n\tif (input.start_column !== undefined) location.startColumn = input.start_column;\n\tif (input.end_column !== undefined) location.endColumn = input.end_column;\n\tif (input.role !== undefined) location.role = input.role;\n\treturn location;\n}\n\nfunction coverageMode(plan: SecurityScanPlan): SecurityCoverage[\"mode\"] {\n\tswitch (plan.target.kind) {\n\t\tcase \"ref_diff\":\n\t\t\treturn \"diff\";\n\t\tcase \"working_tree\":\n\t\t\treturn \"working_tree\";","sourceCodeStart":101,"sourceCodeEnd":137,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/security/publication.ts#L101-L137","documentation":"toLocation checks the normalized finding path against the immutable scan scope recorded in the plan (target include/exclude globs). Findings may only reference files inside the paths that were actually scanned; anything outside is rejected so published results cannot claim issues in unscanned or out-of-scope locations.","triggerScenarios":"Calling the security publish tool with a finding whose path, while repository-relative, does not match plan.target.includePaths or is matched by plan.target.excludePaths — e.g. scanning src/ but publishing a finding in docs/, or the plan's includes changed between scan and publish.","commonSituations":"The LLM invents locations outside the scanned directory, publishing findings from a previous scan against a new plan, typos in include globs (e.g. 'src' vs 'source'), or intentionally excluded vendor/node_modules paths.","solutions":["Move or drop findings whose paths fall outside the plan's target include globs","Re-run the scan with includePaths covering the file the finding refers to","Verify the path does not hit an excludePaths glob (vendor, dist, node_modules)","Re-publish against the plan that was actually used for the scan"],"exampleFix":"// before (plan includes only 'src/**')\nfindings: [{ ..., locations: [{ path: \"docs/notes.md\", start_line: 1 }] }]\n// after\nfindings: [{ ..., locations: [{ path: \"src/app.ts\", start_line: 1 }] }]","handlingStrategy":"validation","validationCode":"if (!pathMatchesSecurityScope(rel, plan.target.includePaths, plan.target.excludePaths)) throw new Error(\"out of scope\");","typeGuard":"null","tryCatchPattern":"try { await publish(params); } catch (e) { if (String(e.message).includes(\"outside the immutable scan scope\")) { /* filter findings or rescan */ } else throw e; }","preventionTips":["Filter findings against plan scope before publishing","Keep include globs aligned with scanned dirs"],"tags":["validation","scope","security"],"backgroundTag":"path-outside-allowed-scope","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}