{"record":{"id":"0efa842d59d7e776","repo":"can1357/oh-my-pi","slug":"import-requires-a-sarif-file-or-codex-security-bun","errorCode":null,"errorMessage":"import requires a SARIF file or Codex Security bundle directory","messagePattern":"import requires a SARIF file or Codex Security bundle directory","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"packages/coding-agent/src/slash-commands/helpers/security.ts","lineNumber":163,"sourceCode":"\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}\n\nasync function exportResults(runtime: SlashCommandRuntime, rest: string): Promise<void> {\n\tconst tokens = parseCommandArgs(rest);\n\tconst scanId = tokens[0];\n\tif (!scanId) throw new Error(\"export requires <scan-id> --output <path> [--format bundle|sarif|report]\");\n\tlet outputPath: string | undefined;\n\tlet format: \"bundle\" | \"sarif\" | \"report\" = \"bundle\";\n\tfor (let index = 1; index < tokens.length; index++) {\n\t\tconst token = tokens[index]!;","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/slash-commands/helpers/security.ts#L145-L181","documentation":"The /security import subcommand loads results from an external source: a SARIF file or a Codex Security bundle directory. importResults() throws this error when parseCommandArgs(rest) yields no source path at all, before any filesystem access happens. It ensures the import has a concrete file or directory to read.","triggerScenarios":"Running /security import with no arguments; rest is empty or whitespace so parseCommandArgs returns an empty token list and the destructured source is undefined.","commonSituations":"Developer forgets the path entirely; an automation interpolates an empty path variable; a UI drops the argument when forwarding the command.","solutions":["Provide the SARIF file path: /security import results.sarif","Or provide a Codex Security bundle directory: /security import ./codex-security-bundle/","Use a path relative to the session cwd or an absolute path; the code resolves it with path.resolve(runtime.cwd, source)"],"exampleFix":"// before\n/security import\n// after\n/security import ./security-report.sarif","handlingStrategy":"validation","validationCode":"import * as fs from \"node:fs\";\nfunction validateImportSource(rest: string): boolean {\n  const [source] = rest.trim().split(/\\s+/).filter(Boolean);\n  return typeof source === \"string\" && source.length > 0;\n}\n// also verify the path exists before invoking:\n// try { fs.statSync(source); } catch { /* resolve path first */ }","typeGuard":null,"tryCatchPattern":"try {\n  await runSlashCommand(`/security import ${source}`);\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith(\"import requires\")) {\n    // no source given: prompt for SARIF file or Codex bundle directory\n  } else throw err;\n}","preventionTips":["Always pass the SARIF file path or Codex Security bundle directory as the first argument","Check that path variables expand to non-empty strings before invoking","Pass a directory (bundle import) or a .sarif file — the command branches on fs.stat().isDirectory()"],"tags":["cli","argument-validation","slash-command","sarif","usage-error"],"backgroundTag":"missing-required-argument","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}