{"record":{"id":"5d56e9767d5e3a49","repo":"microsoft/TypeScript","slug":"expected-inputdir-to-be-a-directory","errorCode":null,"errorMessage":"Expected ${inputDir} to be a directory","messagePattern":"Expected (.+?) to be a directory","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/produceLKG.mjs","lineNumber":34,"sourceCode":"    console.log(`Building LKG from ${source} to ${dest}`);\r\n    await fs.promises.rm(dest, { recursive: true, force: true });\r\n    await fs.promises.mkdir(dest, { recursive: true });\r\n    await copyLibFiles();\r\n    await copyLocalizedDiagnostics();\r\n    await copyTypesMap();\r\n    await copyScriptOutputs();\r\n    await copyDeclarationOutputs();\r\n    await writeGitAttributes();\r\n}\r\n\r\nasync function copyLibFiles() {\r\n    await copyFilesWithGlob(\"lib?(.*).d.ts\");\r\n}\r\n\r\nasync function copyLocalizedDiagnostics() {\r\n    for (const d of localizationDirectories) {\r\n        const inputDir = path.join(source, d);\r\n        if (!fs.statSync(inputDir).isDirectory()) throw new Error(`Expected ${inputDir} to be a directory`);\r\n        const outputDir = path.join(dest, d);\r\n        await fs.promises.mkdir(outputDir, { recursive: true });\r\n        for (const f of await fs.promises.readdir(inputDir)) {\r\n            const inputFile = path.join(inputDir, f);\r\n            if (!fs.statSync(inputFile).isFile()) throw new Error(`Expected ${inputFile} to be a file`);\r\n            const outputFile = path.join(outputDir, f);\r\n            await fs.promises.copyFile(inputFile, outputFile);\r\n        }\r\n    }\r\n}\r\n\r\nasync function copyTypesMap() {\r\n    await copyFromBuiltLocal(\"typesMap.json\"); // Cannot accommodate copyright header\r\n}\r\n\r\nasync function copyScriptOutputs() {\r\n    await copyFromBuiltLocal(\"tsc.js\");\r\n    await copyFromBuiltLocal(\"_tsc.js\");\r","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/microsoft/TypeScript/blob/b465fdbfe175304d9b977da137b2c178ae1091d3/scripts/produceLKG.mjs#L16-L52","documentation":"produceLKG.mjs copies each localization directory from `source` to `dest`. For every name in localizationDirectories it stats the source path and throws if it isn't a directory, so a partial localization build can't be copied into the LKG.","triggerScenarios":"A name in localizationDirectories resolves to a non-existent path or a file rather than a directory under `source`.","commonSituations":"Skipping the localize/L10n build step; a stray file where a directory is expected; previous build left inconsistent state.","solutions":["Run the full localization build before invoking produceLKG.","Inspect the path in the error message and ensure it exists as a directory.","Clean `built/` (`git clean -fdx built/`) and rebuild end-to-end."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import fs from \"fs\";\nfor (const d of localizationDirectories) {\n  const p = path.join(source, d);\n  const st = fs.statSync(p);\n  if (!st.isDirectory()) throw new Error(`Expected ${p} to be a directory`);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run the localization build before produceLKG.","Clean built/ before producing an LKG from a known state."],"tags":["lkg","localization","build","validation"],"backgroundTag":null,"analyzedSha":"b465fdbfe175304d9b977da137b2c178ae1091d3","analyzedAt":"2026-08-12T05:38:42.698Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}