{"record":{"id":"10f19e234ffd0558","repo":"affaan-m/ECC","slug":"invalid-flag-expected-a-single-cache-path-segm","errorCode":null,"errorMessage":"Invalid ${flag}: expected a single cache path segment","messagePattern":"Invalid (.+?): expected a single cache path segment","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/codex/check-plugin-cache.js","lineNumber":41,"sourceCode":"    '  --marketplace <name> Marketplace cache name (default: ecc)',\n    '  --plugin <name>      Plugin cache name (default: ecc)',\n    '  --version <version>  Plugin version (default: package.json version)',\n    '  --help              Show this help text',\n  ].join('\\n'));\n}\n\nfunction validateCacheSegment(flag, value) {\n  if (\n    typeof value !== 'string' ||\n    value.trim() === '' ||\n    value.includes('\\0') ||\n    value.includes('..') ||\n    value.includes('/') ||\n    value.includes('\\\\') ||\n    path.isAbsolute(value) ||\n    path.win32.isAbsolute(value)\n  ) {\n    throw new Error(`Invalid ${flag}: expected a single cache path segment`);\n  }\n  return value;\n}\n\nfunction parseArgs(argv) {\n  const defaults = {\n    marketplace: 'ecc',\n    plugin: 'ecc',\n    version: PACKAGE_JSON.version,\n    codexHome: process.env.CODEX_HOME || path.join(os.homedir(), '.codex'),\n    pluginDir: null,\n  };\n  const optionKeys = {\n    '--codex-home': 'codexHome',\n    '--plugin-dir': 'pluginDir',\n    '--marketplace': 'marketplace',\n    '--plugin': 'plugin',\n    '--version': 'version',","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/codex/check-plugin-cache.js#L23-L59","documentation":"The validateCacheSegment() function in check-plugin-cache.js enforces that --marketplace, --plugin, and --version values are single path segments with no directory traversal. It rejects empty strings, null bytes, '..', '/', '\\', and absolute paths on both POSIX and Windows. This is a security guard preventing path traversal attacks on the Codex plugin cache directory, which is constructed via path.join(codexHome, 'plugins', 'cache', marketplace, plugin, version).","triggerScenarios":"Passing --marketplace '../etc', --plugin 'foo/bar', --version '1.0/../../', or any value containing backslashes, forward slashes, dot-dot, null bytes, or that is empty. Also triggered when an environment variable feeding these values contains unexpected characters.","commonSituations":"Attempting to point the cache checker at a plugin nested outside the cache root; shell scripts that interpolate user-controlled paths into --marketplace or --plugin; Windows users whose values inadvertently contain backslash path separators.","solutions":["Use simple alphanumeric or hyphenated names for --marketplace and --plugin (e.g. 'ecc')","For --version, use the exact version string from package.json (e.g. '2.2.0') without path separators","If you need to check a specific directory, use --plugin-dir with an absolute path instead of manipulating --marketplace/--plugin/--version"],"exampleFix":"// before\nnode scripts/codex/check-plugin-cache.js --marketplace ../custom --plugin my/plugin\n// after\nnode scripts/codex/check-plugin-cache.js --marketplace ecc --plugin ecc\n// or point directly:\nnode scripts/codex/check-plugin-cache.js --plugin-dir /abs/path/to/cache","handlingStrategy":"validation","validationCode":"// Validate cache segment values before passing them as CLI arguments\nfunction isValidCacheSegment(value) {\n  return typeof value === 'string'\n    && value.trim() !== ''\n    && !value.includes('\\0')\n    && !value.includes('..')\n    && !value.includes('/')\n    && !value.includes('\\\\')\n    && !require('path').isAbsolute(value)\n    && !require('path').win32.isAbsolute(value);\n}\n\nconst marketplace = process.env.PLUGIN_MARKETPLACE || 'ecc';\nif (!isValidCacheSegment(marketplace)) {\n  throw new Error(`Invalid marketplace segment: ${marketplace}`);\n}","typeGuard":"// Type guard for a safe cache path segment\nfunction isSafeCacheSegment(value) {\n  return typeof value === 'string'\n    && /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/.test(value);\n}","tryCatchPattern":"try {\n  const options = parseArgs(process.argv.slice(2));\n} catch (error) {\n  if (error.message.includes('expected a single cache path segment')) {\n    console.error('Cache segment values must be simple names without path separators or traversal.');\n    console.error('Use --plugin-dir <abs-path> to check a specific directory instead.');\n    process.exit(2);\n  }\n  throw error;\n}","preventionTips":["Use only alphanumeric names with hyphens or dots for --marketplace, --plugin, --version","Never interpolate user-controlled or file-path-derived values into these flags","If you need to check an arbitrary directory, use --plugin-dir instead"],"tags":["security","path-traversal","cli","argument-parsing","codex"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}