Skip to content

Commit 988c8de

Browse files
committed
feat: better support pnpm symlinked node modules
Latest NextJS evals with Turbopack fail with errors like: ``` [6:57 PM]> Build error occurred Error [TurbopackInternalError]: Symlink node_modules is invalid, it points out of the filesystem root Debug info: - Execution of get_all_written_entrypoints_with_issues_operat ``` We can fix this by operating in temporary workspace directories _inside_ the ".web-codegen-scorer" directory.
1 parent e6beee4 commit 988c8de

2 files changed

Lines changed: 14 additions & 3 deletions

File tree

runner/configuration/constants.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@ export const DEFAULT_SUMMARY_MODEL = 'gemini-2.5-flash-lite';
2323
/** Name of the root folder where we store LLM-generated code for debugging */
2424
export const LLM_OUTPUT_DIR = join(rootDir, 'llm-output');
2525

26+
/**
27+
* Path for WCS temporary directories.
28+
*
29+
* We want temporary workspaces to be nested inside the root project to
30+
* better support symlinked node modules. E.g. Turbopack will otherwise
31+
* fail if symlinked node modules are not reachable via parent directories.
32+
*/
33+
export const WCS_BASE_TMP_DIR = join(rootDir, 'tmp-workspaces');
34+
2635
/**
2736
* Number of times we'll try to ask LLM to repair a build failure,
2837
* providing the build output and the code that causes the problem.

runner/orchestration/file-system.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import {tmpdir} from 'os';
2-
import {LLM_OUTPUT_DIR} from '../configuration/constants.js';
1+
import {LLM_OUTPUT_DIR, WCS_BASE_TMP_DIR} from '../configuration/constants.js';
32
import {Environment} from '../configuration/environment.js';
43
import {
54
copyFolderExcept,
@@ -25,13 +24,15 @@ const PENDING_INSTALLS = new Map<string, Promise<void>>();
2524
* @param env Environment that is currently being run.
2625
* @param rootPromptDef Definition of the root prompt.
2726
* @param progress Logger to use to log out the current progress.
27+
* @param tmpdirBasePath Base path for temporary directories (like `/tmp`).
2828
* @param outputDirectory Custom output directory specified by the user.
2929
* @returns Temporary directory in which to build and a function used to clean in up.
3030
*/
3131
export async function setupProjectStructure(
3232
env: Environment,
3333
rootPromptDef: RootPromptDefinition,
3434
progress: ProgressLogger,
35+
tmpdirBasePath: string = WCS_BASE_TMP_DIR,
3536
outputDirectory?: string,
3637
) {
3738
let directory: string;
@@ -48,7 +49,8 @@ export async function setupProjectStructure(
4849
cleanup = () => Promise.resolve();
4950
} else {
5051
// When outputting to the temporary directory, make sure that the directory is unique.
51-
directory = await mkdtemp(join(tmpdir(), `fw-${env.id}-build-${rootPromptDef.name}`));
52+
await mkdir(tmpdirBasePath, {recursive: true});
53+
directory = await mkdtemp(join(tmpdirBasePath, `fw-${env.id}-build-${rootPromptDef.name}`));
5254

5355
cleanup = async () => {
5456
try {

0 commit comments

Comments
 (0)