{"record":{"id":"1b1742e8d32fafb5","repo":"can1357/oh-my-pi","slug":"show-requires-a-scan-id-or-security-uri","errorCode":null,"errorMessage":"show requires a scan id or security:// URI","messagePattern":"show requires a scan id or security:// URI","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"info","filePath":"packages/coding-agent/src/slash-commands/helpers/security.ts","lineNumber":154,"sourceCode":"\nfunction scanIdFromInput(value: string): string {\n\tconst trimmed = value.trim();\n\tconst match = trimmed.match(/^security:\\/\\/scans\\/([^/]+)/);\n\treturn match?.[1] ?? trimmed;\n}\n\nfunction findingTarget(value: string): { uri: string; scanId: string; findingId: string } {\n\tconst trimmed = value.trim();\n\tconst uriMatch = trimmed.match(/^security:\\/\\/scans\\/([^/]+)\\/findings\\/([^/]+)$/);\n\tif (uriMatch) return { uri: trimmed, scanId: uriMatch[1]!, findingId: uriMatch[2]! };\n\tconst [scanId, findingId] = parseCommandArgs(trimmed);\n\tif (!scanId || !findingId) throw new Error(\"validate requires a finding URI or <scan-id> <finding-id>\");\n\treturn { uri: `security://scans/${scanId}/findings/${findingId}`, scanId, findingId };\n}\n\nasync function showResource(runtime: SlashCommandRuntime, rest: string): Promise<void> {\n\tconst raw = rest.trim();\n\tif (!raw) throw new Error(\"show requires a scan id or security:// URI\");\n\tconst uri = raw.startsWith(\"security://\") ? raw : `security://scans/${scanIdFromInput(raw)}`;\n\tconst handler = new SecurityProtocolHandler(undefined, () => true);\n\tconst resource = await handler.resolve(parseInternalUrl(uri), { cwd: runtime.cwd });\n\tawait runtime.output(resource.content);\n}\n\nasync function importResults(runtime: SlashCommandRuntime, rest: string): Promise<void> {\n\tconst [source] = parseCommandArgs(rest);\n\tif (!source) throw new Error(\"import requires a SARIF file or Codex Security bundle directory\");\n\tconst store = await SecurityStore.openForCwd(runtime.cwd);\n\tconst absolute = path.resolve(runtime.cwd, source);\n\tconst stats = await fs.stat(absolute);\n\tconst bundle = stats.isDirectory()\n\t\t? await importCodexSecurityBundle(absolute, { repositoryRoot: store.repositoryRoot })\n\t\t: await importSarifFile(absolute, { repositoryRoot: store.repositoryRoot });\n\tawait store.putBundle(bundle);\n\tawait runtime.output(`Imported ${bundle.findings.length} finding(s) as security scan ${bundle.scan.id}.`);\n}","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/slash-commands/helpers/security.ts#L136-L172","documentation":"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.","triggerScenarios":"Running /security show with no arguments at all (rest.trim() is the empty string); the command is invoked programmatically with an empty rest string.","commonSituations":"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.","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"],"exampleFix":"// before\n/security show\n// after\n/security show scan-abc\n// or\n/security show security://scans/scan-abc","handlingStrategy":"validation","validationCode":"function validateShowTarget(rest: string): boolean {\n  const raw = rest.trim();\n  return raw.length > 0;\n}\n// skip issuing /security show when raw is empty; use the list subcommand instead","typeGuard":"function hasShowTarget(rest: string | undefined): rest is string {\n  return typeof rest === \"string\" && rest.trim().length > 0;\n}","tryCatchPattern":"try {\n  await runSlashCommand(`/security show ${target}`);\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith(\"show requires\")) {\n    // no target given: show scan list instead\n  } else throw err;\n}","preventionTips":["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"],"tags":["cli","argument-validation","slash-command","usage-error"],"backgroundTag":"missing-required-argument","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}