{"record":{"id":"4b5a2a4f361fedfc","repo":"Kong/insomnia","slug":"extends-target-must-stay-within-the-ruleset-s-ro","errorCode":null,"errorMessage":"\"extends\" target must stay within the ruleset's root directory: ${absolute}","messagePattern":"\"extends\" target must stay within the ruleset's root directory: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/insomnia/src/main/bundle-spectral-ruleset.ts","lineNumber":39,"sourceCode":"\n// Safety checks for local-file extends entries:\n// - Depth / cycle guard against infinite recursion.\n// - Extension check ensures we only load YAML files.\n// - rootDir guard prevents path traversal (e.g. '../../../etc/passwd') from\n//   reaching files outside the directory of the originally-selected ruleset.\nfunction assertAllowed(absolute: string, visited: Set<string>, depth: number, rootDir: string): void {\n  if (depth > MAX_EXTENDS_DEPTH) {\n    throw new Error(`\"extends\" nested too deeply (max ${MAX_EXTENDS_DEPTH}) at ${absolute}`);\n  }\n  if (visited.has(absolute)) {\n    throw new Error(`\"extends\" cycle detected at ${absolute}`);\n  }\n  if (!ALLOWED_EXTENSIONS.includes(path.extname(absolute).toLowerCase())) {\n    throw new Error(`\"extends\" target must be a .yaml or .yml file: ${absolute}`);\n  }\n  const rel = path.relative(rootDir, absolute);\n  if (rel.startsWith('..') || path.isAbsolute(rel)) {\n    throw new Error(`\"extends\" target must stay within the ruleset's root directory: ${absolute}`);\n  }\n}\n\n// Reads a local ruleset file from disk and parses it.\nasync function readRuleset(absolute: string): Promise<Ruleset> {\n  const raw = await fs.promises.readFile(absolute, { encoding: 'utf8' });\n  const parsed = YAML.parse(raw);\n  if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {\n    throw new Error(`Ruleset at ${absolute} must be an object at the top level.`);\n  }\n  return parsed as Ruleset;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n  return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\n// Shallow-merges top-level keys from source into target.","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/Kong/insomnia/blob/d9bb2b0142600f21309832daea3317942d285984/packages/insomnia/src/main/bundle-spectral-ruleset.ts#L21-L57","documentation":"Error \"\"extends\" target must stay within the ruleset's root directory: ${absolute}\" thrown in Kong/insomnia.","triggerScenarios":"Thrown at packages/insomnia/src/main/bundle-spectral-ruleset.ts:39 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":[],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"d9bb2b0142600f21309832daea3317942d285984","analyzedAt":"2026-08-26T18:04:05.187Z","schemaVersion":2},"datasetVersion":"2026-08-26T21:11:00.512Z"}