{"record":{"id":"eeb9d68278528da6","repo":"firecrawl/open-lovable","slug":"unable-to-read-file-normalizedpath","errorCode":null,"errorMessage":"Unable to read file: ${normalizedPath}","messagePattern":"Unable to read file: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/morph-fast-apply.ts","lineNumber":115,"sourceCode":"    } catch {}\n    // fallback to absolute path\n    try {\n      const resAbs = await sandbox.runCommand(`cat ${fullPath}`);\n      if (resAbs && typeof resAbs.stdout === 'string') {\n        return resAbs.stdout as string;\n      }\n    } catch {}\n  }\n\n  // Try shell cat via commands.run\n  if (sandbox?.commands?.run) {\n    const result = await sandbox.commands.run(`cat ${fullPath}`, { cwd: '/home/user/app', timeout: 30 });\n    if (result?.exitCode === 0 && typeof result?.stdout === 'string') {\n      return result.stdout as string;\n    }\n  }\n\n  throw new Error(`Unable to read file: ${normalizedPath}`);\n}\n\n// Write a file to sandbox and update cache\nasync function writeFileToSandbox(sandbox: any, normalizedPath: string, fullPath: string, content: string): Promise<void> {\n  // Provider pattern (writeFile)\n  if (typeof sandbox?.writeFile === 'function') {\n    await sandbox.writeFile(normalizedPath, content);\n    return;\n  }\n\n  // Provider pattern (runCommand redirect)\n  if (typeof sandbox?.runCommand === 'function') {\n    // Ensure directory exists\n    const dir = normalizedPath.includes('/') ? normalizedPath.substring(0, normalizedPath.lastIndexOf('/')) : '';\n    if (dir) {\n      try { await sandbox.runCommand(`mkdir -p ${dir}`); } catch {}\n    }\n    // Write via heredoc with proper escaping","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/firecrawl/open-lovable/blob/69bd93bae7a9c97ef989eb70aabe6797fb3dac89/lib/morph-fast-apply.ts#L97-L133","documentation":"readFileFromSandbox tries one or more mechanisms (provider readFile API, shell cat) to read a file from the sandbox and throws this error if every attempt fails or returns non-zero exit. It signals the requested file could not be retrieved from the sandbox filesystem, often because it does not exist or the sandbox API is not available.","triggerScenarios":"The file at normalizedPath does not exist inside /home/user/app in the sandbox; `cat` exits non-zero (permissions, missing file); the sandbox object exposes neither a readFile method nor commands.run; or the command output is not a string.","commonSituations":"Applying an edit to a path that was never created in the sandbox; path casing or typo mismatches (e.g. /src/App.jsx vs app.jsx); sandbox freshly provisioned and empty; using a custom/mock sandbox object lacking the expected API surface.","solutions":["Verify the file actually exists at that path inside the sandbox (run `ls` or check the file cache) before reading.","Check for path typos, wrong case, or missing directories in normalizedPath.","Use the provider's native readFile method instead of the shell fallback.","Ensure the sandbox object is a supported provider instance (e2b/vercel) exposing commands.run.","Catch the error and treat it as 'create new file' when the edit should create a missing file."],"exampleFix":"// before\nconst current = await readFileFromSandbox(sandbox, path);\n// after\nlet current = '';\ntry {\n  current = await readFileFromSandbox(sandbox, path);\n} catch {\n  current = ''; // new file: apply edit to empty content\n}","handlingStrategy":"try-catch","validationCode":"const exists = await sandbox.commands.run(`test -f ${fullPath} && echo yes || echo no`, { cwd: '/home/user/app' });\nif (exists.stdout.trim() !== 'yes') {\n  // skip read; treat as new file\n}","typeGuard":"function canReadFile(r: unknown): r is { stdout: string; exitCode: number } {\n  return !!r && typeof r === 'object' && typeof (r as any).stdout === 'string' && typeof (r as any).exitCode === 'number';\n}","tryCatchPattern":"try {\n  const content = await readFileFromSandbox(sandbox, path);\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith('Unable to read file')) {\n    console.warn(`File ${path} not readable in sandbox; treating as new file`);\n    return ''; // or skip this edit\n  }\n  throw err;\n}","preventionTips":["Check file existence (test -f or provider list API) before reading.","Normalize paths consistently (resolve relative to /home/user/app) before every call.","Keep the sandbox fileCache in sync so cached paths match real sandbox files.","Handle 'missing file' as create-new-file instead of failing the whole edit batch.","Log the path and sandbox id on failure to distinguish wrong-path from dead-sandbox issues."],"tags":["filesystem","sandbox","io"],"backgroundTag":"file-not-found","analyzedSha":"69bd93bae7a9c97ef989eb70aabe6797fb3dac89","analyzedAt":"2026-08-28T22:20:32.339Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}