{"record":{"id":"acd8b86167cd4aeb","repo":"pbakaus/impeccable","slug":"invalid-svelte-component-source-file-acd8b8","errorCode":null,"errorMessage":"Invalid svelte-component source file","messagePattern":"Invalid svelte-component source file","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"skill/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/skill/scripts/live/svelte-component.mjs#L426-L462","documentation":"Thrown by resolveSourceFile() in live/svelte-component.mjs when the supplied sourceFile is falsy (empty/null/undefined) OR is an absolute path. The function only resolves project-relative paths so it can sandbox the resolved file under the project root; an absolute path would bypass that sandbox. This is the first guard before the escape and existence checks.","triggerScenarios":"resolveSourceFile(sourceFile, cwd) is called with sourceFile = '', null, undefined, or an absolute path like '/home/user/proj/src/Foo.svelte' or 'C:\\\\proj\\\\src\\\\Foo.svelte'. path.isAbsolute() returns true for leading '/' or a drive letter.","commonSituations":"Caller passes path.resolve() output (already absolute) instead of the relative specifier; a config field for the component path is empty; a default value of '' leaked through; Windows drive-letter paths; the value was taken from __dirname/import.meta.url resolution.","solutions":["Pass a project-relative path, e.g. 'src/lib/Foo.svelte', not an absolute one.","If you computed an absolute path, convert it: path.relative(cwd, absPath) before calling.","Ensure the sourceFile argument is a non-empty string at the call site."],"exampleFix":"// before\nresolveSourceFile(path.resolve(cwd, 'src/Foo.svelte'), cwd)\n// after\nresolveSourceFile('src/Foo.svelte', cwd)","handlingStrategy":"validation","validationCode":"if (!sourceFile || (typeof sourceFile === 'string' && path.isAbsolute(sourceFile))) {\n  throw new Error('sourceFile must be a project-relative path');\n}","typeGuard":"function isRelativeSpecifier(v: unknown): v is string {\n  return typeof v === 'string' && v.length > 0 && !path.isAbsolute(v);\n}","tryCatchPattern":null,"preventionTips":["Store and pass component paths as project-relative specifiers, never resolved absolute paths.","If you resolve for display, keep the relative form for the call argument.","Reject empty/absolute values at the config-loading boundary."],"tags":["svelte","path","validation","live-adapter"],"backgroundTag":null,"analyzedSha":"d14711ae3d1a1dd62dee61a358d27f107c51ccd0","analyzedAt":"2026-08-13T00:52:25.771Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}