can1357/oh-my-pi · error · ToolError
ref_diff preflight requires base_revision and head_revision
Error message
ref_diff preflight requires base_revision and head_revision
What it means
For target_kind='ref_diff', the scan compares two git revisions, so both base_revision and head_revision are required. If either is missing/empty, targetFromParams throws this preflight ToolError before any scanning starts.
Source
Thrown at packages/coding-agent/src/tools/security-scan.ts:72
cloudStats?: CodexSecurityCloudStats;
cloudScan?: { id: string; repositoryUrl: string };
importedScan?: { id: string; findingCount: number };
}
function targetFromParams(params: SecurityScanParams): SecurityTargetRequest {
const common = { includePaths: params.include_paths, excludePaths: params.exclude_paths };
switch (params.target_kind ?? "repository") {
case "scoped_path": {
if (!params.include_paths?.some(value => value.trim().length > 0)) {
throw new ToolError("scoped_path security scans require at least one include path");
}
return { kind: "scoped_path", includePaths: params.include_paths, excludePaths: params.exclude_paths };
}
case "working_tree":
return { kind: "working_tree", ...common };
case "ref_diff":
if (!params.base_revision || !params.head_revision) {
throw new ToolError("ref_diff preflight requires base_revision and head_revision");
}
return {
kind: "ref_diff",
baseRevision: params.base_revision,
headRevision: params.head_revision,
...common,
};
default:
return { kind: "repository", ...common };
}
}
function requireValue(value: string | undefined, label: string): string {
if (!value?.trim()) throw new ToolError(`${label} is required for this action`);
return value.trim();
}
function cloudClientForSession(session: ToolSession, credentialId?: number): CodexSecurityCloudClient {View on GitHub (pinned to 9690622007)
Solutions
- Supply both base_revision and head_revision (branch names, tags, or SHAs), e.g. { target_kind: "ref_diff", base_revision: "main", head_revision: "HEAD" }
- If you actually want the current state scanned, use target_kind='working_tree' or 'repository' instead
- Validate both revision strings are non-empty before invoking
Example fix
// before
scan({ target_kind: "ref_diff", head_revision: "HEAD" });
// after
scan({ target_kind: "ref_diff", base_revision: "main", head_revision: "HEAD" }); Defensive patterns
Strategy: validation
Validate before calling
if (params.target_kind === "ref_diff" && (!params.base_revision?.trim() || !params.head_revision?.trim())) throw new Error("ref_diff needs both base_revision and head_revision"); Try / catch
try { await securityScan(params); } catch (e) { if (e instanceof ToolError && e.message.includes("ref_diff preflight")) { return securityScan({ ...params, base_revision: params.base_revision || "main", head_revision: params.head_revision || "HEAD" }); } throw e; } Prevention
- Resolve both refs against the repo (git rev-parse) before scanning
- Use 'HEAD' and a base branch explicitly rather than relying on defaults
- Switch to working_tree kind when you don't actually need a diff
When it happens
Trigger: Calling security-scan with target_kind='ref_diff' and omitting base_revision, head_revision, or both; passing empty strings for either.
Common situations: Model forgets the revision pair when it wants to scan a diff; caller has only one of the two refs (e.g. HEAD but no base branch name); empty-string values from unset variables.
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
- Cannot resolve revision: ${options.revision}
- lookbackDays must be a positive integer or 'all'
- Security scan contains duplicate finding ids
- Security scan manifest contains duplicate finding references
- Finding ${finding.id} belongs to ${finding.scanId}, expected
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/060d9daf6a5cfdb6.
Report an issue: GitHub.