{"record":{"id":"70363e600c1eddaf","repo":"halo-dev/halo","slug":"shared-dependency-root-resolved-to-packagejso","errorCode":null,"errorMessage":"Shared dependency ${root} resolved to ${packageJson.name || \"an unnamed package\"} at ${packageRoot}.","messagePattern":"Shared dependency (.+?) resolved to (.+?) at (.+?)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"info","filePath":"ui/packages/ui-plugin-bundler-kit/src/runtime-snapshot.ts","lineNumber":138,"sourceCode":"  try {\n    packageJsonPath = await resolvePackageJSON(root, {\n      from: resolutionBase,\n      conditions: [\"browser\", \"import\", \"default\"],\n    });\n  } catch (error) {\n    throw new Error(\n      `Cannot resolve shared dependency ${root} from ${resolutionBase}.`,\n      { cause: error }\n    );\n  }\n  const packageRoot = fs.realpathSync(path.dirname(packageJsonPath));\n  const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, \"utf8\")) as {\n    name?: string;\n    version?: string;\n  };\n\n  if (packageJson.name !== root || !packageJson.version) {\n    throw new Error(\n      `Shared dependency ${root} resolved to ${packageJson.name || \"an unnamed package\"} at ${packageRoot}.`\n    );\n  }\n\n  return {\n    name: packageJson.name,\n    version: packageJson.version,\n    packageRoot,\n  };\n}\n\nexport async function validateResolvedSharedPackage(\n  root: SharedPackageRoot,\n  providerRoot: string,\n  snapshot: HaloHostRuntimeSnapshot,\n  sourceId?: string\n) {\n  const resolved = await resolveSharedPackage(root, providerRoot, sourceId);","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/halo-dev/halo/blob/d2f5165f9c8f055ffcb3fa9c3f4032821a7b68c8/ui/packages/ui-plugin-bundler-kit/src/runtime-snapshot.ts#L120-L156","documentation":"processAutoLoginCookie parses token[1] as the expiry epoch and throws InvalidCookieException when it is in the past (tokenExpiryTime < System.currentTimeMillis()). handleError cancels the cookie and returns Mono.empty(), so the effect is a silent re-login prompt rather than an error page.","triggerScenarios":"A returning user presents a remember-me cookie whose stored expiry timestamp has passed the configured token validity period (default two weeks).","commonSituations":"User returns after the remember-me validity elapsed; server clock skew; validity shortened in config leaving older cookies 'expired'.","solutions":["User logs in again to obtain a fresh remember-me cookie.","Increase the remember-me token validity (halo.security.remember-me.token-validity) if users are being logged out too soon.","Ensure server clocks are NTP-synced so expiries are not computed prematurely."],"exampleFix":"// application.yaml (halo config) — extend validity\nspring:\n  security:\n    rememberme:\n      tokenValiditySeconds: 2592000 # 30 days","handlingStrategy":"fallback","validationCode":"// Framework-owned flow. To pre-check expiry of a known token shape:\nlong expiry = Long.parseLong(tokens[1]);\nif (expiry < System.currentTimeMillis()) {\n    // expire cookie and prompt re-login rather than submitting\n}","typeGuard":null,"tryCatchPattern":"autoLogin(exchange)\n    .onErrorResume(InvalidCookieException.class, e -> {\n        log.debug(\"Remember-me expired; user must re-authenticate\");\n        return Mono.empty();\n    })","preventionTips":["Set a token validity that matches user session expectations.","Keep server clocks NTP-synced.","Treat expiry as expected behavior — prompt re-login, don't alarm users."],"tags":["security","remember-me","cookie","authentication","expiry"],"backgroundTag":null,"analyzedSha":"d2f5165f9c8f055ffcb3fa9c3f4032821a7b68c8","analyzedAt":"2026-08-14T00:18:38.915Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}