can1357/oh-my-pi · info
show requires a scan id or security:// URI
Error message
show requires a scan id or security:// URI
What it means
The /security show subcommand needs a target resource: either a scan id (used to build security://scans/<id>) or a full security:// URI. showResource() throws this error when the rest of the command line is empty after trimming, so there is nothing to resolve via SecurityProtocolHandler.resolve(). It guards against running show with no target.
Source
Thrown at packages/coding-agent/src/slash-commands/helpers/security.ts:154
function scanIdFromInput(value: string): string {
const trimmed = value.trim();
const match = trimmed.match(/^security:\/\/scans\/([^/]+)/);
return match?.[1] ?? trimmed;
}
function findingTarget(value: string): { uri: string; scanId: string; findingId: string } {
const trimmed = value.trim();
const uriMatch = trimmed.match(/^security:\/\/scans\/([^/]+)\/findings\/([^/]+)$/);
if (uriMatch) return { uri: trimmed, scanId: uriMatch[1]!, findingId: uriMatch[2]! };
const [scanId, findingId] = parseCommandArgs(trimmed);
if (!scanId || !findingId) throw new Error("validate requires a finding URI or <scan-id> <finding-id>");
return { uri: `security://scans/${scanId}/findings/${findingId}`, scanId, findingId };
}
async function showResource(runtime: SlashCommandRuntime, rest: string): Promise<void> {
const raw = rest.trim();
if (!raw) throw new Error("show requires a scan id or security:// URI");
const uri = raw.startsWith("security://") ? raw : `security://scans/${scanIdFromInput(raw)}`;
const handler = new SecurityProtocolHandler(undefined, () => true);
const resource = await handler.resolve(parseInternalUrl(uri), { cwd: runtime.cwd });
await runtime.output(resource.content);
}
async function importResults(runtime: SlashCommandRuntime, rest: string): Promise<void> {
const [source] = parseCommandArgs(rest);
if (!source) throw new Error("import requires a SARIF file or Codex Security bundle directory");
const store = await SecurityStore.openForCwd(runtime.cwd);
const absolute = path.resolve(runtime.cwd, source);
const stats = await fs.stat(absolute);
const bundle = stats.isDirectory()
? await importCodexSecurityBundle(absolute, { repositoryRoot: store.repositoryRoot })
: await importSarifFile(absolute, { repositoryRoot: store.repositoryRoot });
await store.putBundle(bundle);
await runtime.output(`Imported ${bundle.findings.length} finding(s) as security scan ${bundle.scan.id}.`);
}View on GitHub (pinned to 9690622007)
Solutions
- Pass a scan id: /security show <scan-id>
- Or pass a full URI: /security show security://scans/<scan-id>[/findings/<finding-id>]
- If you want an overview of scans rather than one resource, use the appropriate list subcommand instead of show
Example fix
// before /security show // after /security show scan-abc // or /security show security://scans/scan-abc
Defensive patterns
Strategy: validation
Validate before calling
function validateShowTarget(rest: string): boolean {
const raw = rest.trim();
return raw.length > 0;
}
// skip issuing /security show when raw is empty; use the list subcommand instead Type guard
function hasShowTarget(rest: string | undefined): rest is string {
return typeof rest === "string" && rest.trim().length > 0;
} Try / catch
try {
await runSlashCommand(`/security show ${target}`);
} catch (err) {
if (err instanceof Error && err.message.startsWith("show requires")) {
// no target given: show scan list instead
} else throw err;
} Prevention
- Never call /security show without an argument — it does not default to a listing
- Resolve empty variables before interpolating into the command string
- Use security:// URIs verbatim when available instead of reconstructing them
When it happens
Trigger: Running /security show with no arguments at all (rest.trim() is the empty string); the command is invoked programmatically with an empty rest string.
Common situations: Developer runs /security show expecting a default listing of scans (show does not list — use the list subcommand instead); an automation sends the command without the id argument; an id variable is empty due to a failed substitution.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- validate requires a finding URI or <scan-id> <finding-id>
- import requires a SARIF file or Codex Security bundle direct
- export requires <scan-id> --output <path> [--format bundle|s
- Unknown export format: ${value}
- Unknown export option: ${token}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/1b1742e8d32fafb5.
Report an issue: GitHub.