{"record":{"id":"0c710c4d4f1d256f","repo":"ruvnet/ruflo","slug":"trajectory-envelope-not-found-path","errorCode":null,"errorMessage":"trajectory envelope not found: ${path}","messagePattern":"trajectory envelope not found: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/browser/src/application/signed-trajectory-service.ts","lineNumber":94,"sourceCode":"    },\n    key,\n    { sealedAt: input.sealedAt },\n  );\n\n  return { envelope, publicKeyHex: key.publicKeyHex };\n}\n\n/** Write a signed envelope to disk. */\nexport async function writeSealedTrajectory(\n  envelope: SignedTrajectoryEnvelope,\n  path: string,\n): Promise<void> {\n  await writeFile(resolvePath(path), JSON.stringify(envelope, null, 2), 'utf8');\n}\n\n/** Read a signed envelope from disk. */\nexport async function readSealedTrajectory(path: string): Promise<SignedTrajectoryEnvelope> {\n  if (!existsSync(path)) throw new Error('trajectory envelope not found: ' + path);\n  const raw = await readFile(resolvePath(path), 'utf8');\n  return JSON.parse(raw) as SignedTrajectoryEnvelope;\n}\n\n/** Verify a sealed envelope. Thin wrapper that allows trust-list filtering. */\nexport function verifySealedTrajectory(\n  envelope: unknown,\n  options: { trustedPublicKeys?: string[] } = {},\n): VerificationResult {\n  return verifyTrajectory(envelope, options);\n}\n\n/**\n * Compute the replay plan from a sealed envelope + mutations.\n *\n * Phase 1 deliberately returns a plan rather than executing — the executor\n * needs a live BrowserService and is wired in BrowserService.replayFromEnvelope.\n * This keeps the signing/replay logic browser-engine-independent so it can be","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/browser/src/application/signed-trajectory-service.ts#L76-L112","documentation":"Thrown by readSealedTrajectory in @claude-flow/browser/src/application/signed-trajectory-service.ts when no file exists at the given path before reading. Paths are resolved with path.resolve (i.e. relative paths resolve against the current working directory), so the check fails both when the envelope was never written and when the process cwd differs from the one used at write time. Note the existsSync check and the readFile both target the resolved path, but a cwd change between writeSealedTrajectory and readSealedTrajectory silently redirects relative paths.","triggerScenarios":"Calling readSealedTrajectory('trajectories/run-1.json') from a process whose cwd is not the directory used when writeSealedTrajectory created the file; reading an envelope id that was never sealed; a typo'd or stale path after the file was moved/deleted; a TOCTOU delete between existsSync and readFile surfaces as ENOENT instead of this message.","commonSituations":"Persisting sealed trajectories in one CLI invocation and replaying them in another (different cwd, so relative resolution diverges); cleanup jobs deleting old envelope files while a consumer still references them; passing a directory or an id instead of the actual file path.","solutions":["Pass an absolute path to both writeSealedTrajectory and readSealedTrajectory (store resolvePath(output) at write time) so cwd cannot diverge","Verify the file exists (existsSync) and log the fully resolved path before calling readSealedTrajectory to catch path mistakes early","If the envelope should exist, re-run the sealing step (sealTrajectory + writeSealedTrajectory) that produces it, then retry the read","Treat a genuinely missing envelope as a cache miss: re-capture the trajectory instead of failing the whole replay pipeline"],"exampleFix":"// before\nawait writeSealedTrajectory(env, 'out/sealed.json'); // cwd A\nawait readSealedTrajectory('out/sealed.json'); // cwd B -> throws not found\n\n// after\nimport { resolve } from 'node:path';\nconst sealedPath = resolve('out/sealed.json');\nawait writeSealedTrajectory(env, sealedPath);\nconst env2 = await readSealedTrajectory(sealedPath);","handlingStrategy":"validation","validationCode":"import { existsSync } from 'node:fs';\nimport { resolve } from 'node:path';\nconst abs = resolve(path);\nif (!existsSync(abs)) throw new Error(`no sealed envelope at ${abs}; seal it first`);\nconst envelope = await readSealedTrajectory(abs);","typeGuard":"const isSignedEnvelope = (v: unknown): v is SignedTrajectoryEnvelope =>\n  typeof v === 'object' && v !== null && 'signature' in v && 'trajectory' in v;","tryCatchPattern":"try { env = await readSealedTrajectory(abs); } catch (e) { if (e instanceof Error && e.message.startsWith('trajectory envelope not found')) { env = await recaptureTrajectory(); /* re-seal + write */ } else throw e; }","preventionTips":["Always pass absolute paths to write/read sealed trajectories","Persist the resolved path at write time and reuse exactly that string when reading","Treat missing envelopes as re-captureable cache misses in replay pipelines"],"tags":["filesystem","trajectory","signed-envelope","path-resolution"],"backgroundTag":"file-not-found","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}