{"record":{"id":"d5472216705f2040","repo":"pbakaus/impeccable","slug":"invalid-svelte-component-source-file","errorCode":null,"errorMessage":"Invalid svelte-component source file","messagePattern":"Invalid svelte-component source file","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"plugin/skills/impeccable/scripts/live/svelte-component.mjs","lineNumber":444,"sourceCode":"        const manifest = readManifest(candidate);\n        if (manifest?.id === id) return { ...manifest, manifestPath: candidate };\n      } catch { /* skip */ }\n    }\n  }\n  return null;\n}\n\nexport function readManifest(manifestPath) {\n  const data = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'));\n  return {\n    ...data,\n    manifestPath,\n  };\n}\n\nexport function resolveSourceFile(sourceFile, cwd = process.cwd()) {\n  if (!sourceFile || path.isAbsolute(sourceFile)) {\n    throw new Error('Invalid svelte-component source file');\n  }\n  const full = path.resolve(cwd, sourceFile);\n  const rel = path.relative(cwd, full);\n  if (!rel || rel.startsWith('..') || path.isAbsolute(rel)) {\n    throw new Error('Svelte-component source file escapes project root');\n  }\n  if (!fs.existsSync(full)) {\n    throw new Error('Svelte-component source file not found: ' + sourceFile);\n  }\n  return full;\n}\n\nfunction appendCssToSvelteStyle(lines, cssLines) {\n  const closeIdx = findLastStyleCloseLine(lines);\n  const prepared = ['', ...cssLines.map((line) => (line.trim() === '' ? '' : '  ' + line.trimStart()))];\n  if (closeIdx === -1) {\n    return [...lines, '', '<style>', ...prepared.slice(1), '</style>'];\n  }","sourceCodeStart":426,"sourceCodeEnd":462,"githubUrl":"https://github.com/pbakaus/impeccable/blob/d14711ae3d1a1dd62dee61a358d27f107c51ccd0/plugin/skills/impeccable/scripts/live/svelte-component.mjs#L426-L462","documentation":"Thrown by resolveSourceFile when the sourceFile argument is falsy or an absolute path. The library requires a project-relative path so it can contain the resolved file inside the project root; absolute paths are rejected up front to avoid the escape check being bypassed.","triggerScenarios":"Calling resolveSourceFile(undefined), resolveSourceFile(''), or resolveSourceFile('/home/user/proj/src/Foo.svelte'). The first guard trips before any filesystem access.","commonSituations":"Passing a user-provided absolute path, a config value that resolved to undefined, or a value that came in without normalization.","solutions":["Pass a path relative to the project root, e.g. 'src/lib/Foo.svelte'.","If you hold an absolute path, convert it: path.relative(projectRoot, absPath).","Ensure the argument is non-empty before calling resolveSourceFile."],"exampleFix":"// before\nresolveSourceFile('/abs/path/Comp.svelte', cwd);\n\n// after\nresolveSourceFile(path.relative(cwd, '/abs/path/Comp.svelte'), cwd);","handlingStrategy":"validation","validationCode":"function isValidRelativeSource(sourceFile, cwd) {\n  return typeof sourceFile === 'string' && sourceFile.length > 0 && !path.isAbsolute(sourceFile);\n}","typeGuard":"function isRelativeSourcePath(sourceFile) {\n  return typeof sourceFile === 'string' && sourceFile.length > 0 && !path.isAbsolute(sourceFile);\n}","tryCatchPattern":"try {\n  resolveSourceFile(sourceFile, cwd);\n} catch (err) {\n  if (err.message === 'Invalid svelte-component source file') {\n    sourceFile = path.relative(cwd, absolutePath);\n  } else throw err;\n}","preventionTips":["Normalize all source paths to project-relative at the system boundary.","Reject absolute paths in config schemas with a JSON-schema 'format: relative-path'.","Keep cwd aligned with the project root the relative paths were computed against."],"tags":["path","validation","svelte","security"],"backgroundTag":null,"analyzedSha":"d14711ae3d1a1dd62dee61a358d27f107c51ccd0","analyzedAt":"2026-08-13T00:52:25.771Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}