{"record":{"id":"049f93bb6c3f4c44","repo":"sinelaw/fresh","slug":"pkg-invalid-package-packagename-validation-error","errorCode":null,"errorMessage":"[pkg] Invalid package '${packageName}': ${validation.error}","messagePattern":"\\[pkg\\] Invalid package '(.+?)': (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/fresh-editor/plugins/pkg.ts","lineNumber":1251,"sourceCode":"\n  if (result.exit_code !== 0) {\n    const errorMsg = gitErrorMessage(result.stderr, \"Clone failed\");\n    packageFailure(`Failed to install ${packageName}: ${errorMsg}`);\n    return false;\n  }\n\n  // Checkout specific version if requested\n  if (version && version !== \"latest\") {\n    const checkoutResult = await checkoutVersion(tempDir, version);\n    if (!checkoutResult) {\n      editor.setStatus(`Installed ${packageName} but failed to checkout version ${version}`);\n    }\n  }\n\n  // Validate package structure\n  const validation = validatePackage(tempDir, packageName);\n  if (!validation.valid) {\n    editor.warn(`[pkg] Invalid package '${packageName}': ${validation.error}`);\n    packageFailure(`Failed to install ${packageName}: ${validation.error}`);\n    // Clean up\n    fsLocal.removePath(tempDir);\n    return false;\n  }\n\n  const manifest = validation.manifest;\n\n  // Use manifest name as the authoritative package name\n  if (manifest?.name) packageName = manifest.name;\n\n  // Determine correct target directory based on actual package type\n  const actualType = manifest?.type || \"plugin\";\n  const correctPackagesDir = actualType === \"plugin\" ? PACKAGES_DIR\n                           : actualType === \"theme\" ? THEMES_PACKAGES_DIR\n                           : actualType === \"bundle\" ? BUNDLES_PACKAGES_DIR\n                           : LANGUAGES_PACKAGES_DIR;\n  const correctTargetDir = editor.pathJoin(correctPackagesDir, packageName);","sourceCodeStart":1233,"sourceCodeEnd":1269,"githubUrl":"https://github.com/sinelaw/fresh/blob/67894ca5463dbd7a89bb31add4627c27d6b79d83/crates/fresh-editor/plugins/pkg.ts#L1233-L1269","documentation":"`editor.warn` from the install flow in pkg.ts:1251: after extracting a downloaded package to `tempDir`, `validatePackage(tempDir, packageName)` reports an invalid structure and the plugin logs `[pkg] Invalid package '${packageName}': ${validation.error}`, calls `packageFailure`, removes the temp dir, and aborts the install (returns false). It means the package archive did not match the expected plugin/theme layout (missing manifest/entry files, wrong name, bad metadata).","triggerScenarios":"Installing a plugin/theme whose extracted contents fail `validatePackage` — missing or malformed package manifest, entry point absent, name mismatch between manifest and requested `packageName`, or unsupported structure.","commonSituations":"Registry entry pointing at a repo with no pkg manifest at its root; package renamed/refactored so declared entry files no longer exist; publishing a source-only repo without build artifacts; corrupted/incomplete download extracted to tempDir.","solutions":["Read `validation.error` to see which structural check failed and fix the package's manifest/entry files at the source","Verify the package repo matches the current pkg package format (manifest + entry point present)","Re-publish or point the registry at a corrected version/tag of the package","Clear caches and retry the install in case the download was corrupted"],"exampleFix":"// before (package repo)\n// repo root has only src/, no pkg manifest\n// after\n// add manifest at repo root:\n// { \"name\": \"my-plugin\", \"entry\": \"dist/main.js\", \"type\": \"plugin\" }","handlingStrategy":"validation","validationCode":"// caller-side check before install\nconst manifest = await fetchPackageManifest(registryEntry);\nif (!manifest || !manifest.name || !manifest.entry) {\n  editor.warn(`[pkg] Skipping ${packageName}: missing manifest fields`);\n  return false;\n}","typeGuard":"function isValidPackageShape(pkg) {\n  return pkg != null && typeof pkg === 'object' && typeof pkg.name === 'string' && pkg.name.length > 0 && typeof pkg.entry === 'string' && pkg.entry.length > 0;\n}","tryCatchPattern":"const ok = await installPackage(name);\nif (!ok) {\n  // installPackage already warned with validation.error and cleaned tempDir\n  editor.setStatus(`Install of ${name} failed: invalid package structure`);\n}","preventionTips":["Validate package manifests in the registry itself so bad entries are caught at publish time","Check that the declared entry file exists in the repo before releasing a package","Pin installs to reviewed tags/versions rather than moving branch heads","Retry downloads once and re-validate to rule out corrupted archives"],"tags":["validation","package-manager","plugin","manifest"],"backgroundTag":"schema-validation-failed","analyzedSha":"67894ca5463dbd7a89bb31add4627c27d6b79d83","analyzedAt":"2026-09-13T15:04:03.701Z","contentChangedAt":"2026-09-13T15:04:03.701Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}