{"record":{"id":"2a102ac803b85c88","repo":"KeygraphHQ/shannon","slug":"config-not-found","errorCode":"CONFIG_NOT_FOUND","errorMessage":"Configuration file not found: ${configPath}","messagePattern":"Configuration file not found: (.+?)","errorType":"validation","errorClass":"PentestError","httpStatus":null,"severity":"error","filePath":"apps/worker/src/config-parser.ts","lineNumber":182,"sourceCode":"      const message = error.message || `validation failed for keyword \"${error.keyword}\"`;\n      return `${path}: ${message}`;\n    }\n  }\n}\n\n/**\n * Format all AJV errors into a list of human-readable messages.\n * Returns an array of formatted error strings.\n */\nfunction formatAjvErrors(errors: ErrorObject[]): string[] {\n  return errors.map(formatAjvError);\n}\n\nexport const parseConfig = async (configPath: string): Promise<Config> => {\n  try {\n    // 1. Verify file exists\n    if (!(await fs.pathExists(configPath))) {\n      throw new PentestError(\n        `Configuration file not found: ${configPath}`,\n        'config',\n        false,\n        { configPath },\n        ErrorCode.CONFIG_NOT_FOUND,\n      );\n    }\n\n    // 2. Check file size\n    const stats = await fs.stat(configPath);\n    const maxFileSize = 1024 * 1024; // 1MB\n    if (stats.size > maxFileSize) {\n      throw new PentestError(\n        `Configuration file too large: ${stats.size} bytes (maximum: ${maxFileSize} bytes)`,\n        'config',\n        false,\n        { configPath, fileSize: stats.size, maxFileSize },\n        ErrorCode.CONFIG_VALIDATION_FAILED,","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/KeygraphHQ/shannon/blob/1ae0a142f8525410a688f0309fd003cc5b1d92de/apps/worker/src/config-parser.ts#L164-L200","documentation":"parseConfig rejects when the supplied config file path does not exist on disk. Classified as ErrorCode.CONFIG_NOT_FOUND, which Temporal treats as a non-retryable ConfigurationError — the run fails immediately rather than retrying.","triggerScenarios":"`./shannon start -u <url> -r <repo> -c ./missing.yaml`; a relative -c path resolved against an unexpected working directory; a typo in the path passed to parseConfig.","commonSituations":"Running the CLI from the wrong directory; the config file not committed to the repo; a path typo; an absolute path with a stale mount inside the worker container.","solutions":["Verify the path exists: `ls -l <config-path>`.","Pass an absolute path to -c to avoid cwd ambiguity.","Create the config from a template under apps/worker/configs/, or omit -c to run with defaults."],"exampleFix":"# before\n./shannon start -u http://app -r repo -c ./config/audit.yaml   # wrong path\n\n# after\n./shannon start -u http://app -r repo -c /abs/path/apps/worker/configs/example.yaml","handlingStrategy":"validation","validationCode":"import { pathExists } from 'zx/fs';\nif (!(await pathExists(configPath))) {\n  throw new Error(`Refusing to parse: config not found at ${configPath}`);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pass an absolute path to -c to avoid cwd-dependent resolution.","Commit config files to the repo or reference them by absolute path in CI."],"tags":["config","filesystem","cli"],"backgroundTag":null,"analyzedSha":"1ae0a142f8525410a688f0309fd003cc5b1d92de","analyzedAt":"2026-08-12T17:40:03.583Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}