{"record":{"id":"160d62a9b063597c","repo":"coding-horror/basic-computer-games","slug":"game-folder-is-missing-a-javascript-folder","errorCode":null,"errorMessage":"Game \"${folder}\" is missing a javascript folder","messagePattern":"Game \"(.+?)\" is missing a javascript folder","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"00_Utilities/build-index.js","lineNumber":93,"sourceCode":"\t\t\t\t</main>\n\t\t\t</article>\n\t\t</body>\n\t`;\n\n\treturn `\n\t\t<!DOCTYPE html>\n\t\t<html lang=\"en\">\n\t\t${head}\n\t\t${body}\n\t\t</html>\n\t`.trim().replace(/\\s\\s+/g, '');\n}\n\nfunction findJSFilesInFolder(folder) {\n\t// filter folders that do not include a subfolder called \"javascript\"\n\tconst hasJavascript = fs.existsSync(`${folder}/${JAVASCRIPT_FOLDER}`);\n\tif (!hasJavascript) {\n\t\tthrow new Error(`Game \"${folder}\" is missing a javascript folder`);\n\t}\n\n\t// get all files in the javascript folder\n\tconst files = fs.readdirSync(`${folder}/${JAVASCRIPT_FOLDER}`);\n\n\t// filter files only allow .html files\n\tconst htmlFiles = files.filter(file => file.endsWith('.html'));\n\tconst mjsFiles = files.filter(file => file.endsWith('.mjs'));\n\tconst entries = [\n\t\t...htmlFiles,\n\t\t...mjsFiles\n\t].filter(file => !IGNORE_FILES.includes(file));\n\n\tif (entries.length == 0) {\n\t\tthrow new Error(`Game \"${folder}\" is missing a HTML or node.js file in the folder \"${folder}/${JAVASCRIPT_FOLDER}\"`);\n\t}\n\n\treturn entries.map(file => path.join(folder, JAVASCRIPT_FOLDER, file));","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/coding-horror/basic-computer-games/blob/5301155192d91d74d337899cecc59dbda59c4c17/00_Utilities/build-index.js#L75-L111","documentation":"Thrown by findJSFilesInFolder() when a game directory lacks a child folder named 'javascript' (the JAVASCRIPT_FOLDER constant). The index builder expects every non-ignored game folder to contain a 'javascript/' subfolder holding the web port. This throw is caught by the try/catch in main() at build-index.js:134-139, so it surfaces as a console warning and the game is simply omitted from index.html rather than crashing the build.","triggerScenarios":"Running `node ./00_Utilities/build-index.js` when a numbered game folder (e.g. '03_Animal') exists without a 'javascript' subfolder; main() calls findJSFilesInFolder for that folder and fs.existsSync returns false at line 91.","commonSituations":"A game has only a Java/Python/C# port and no JavaScript port yet; a folder was renamed/moved leaving an empty stub; a new game folder was added before its javascript/ implementation.","solutions":["Confirm the game has a javascript port; if not, this is expected behavior and the warning can be ignored.","If it should be skipped silently, add the folder prefix to IGNORE_FOLDERS_START_WITH at build-index.js:16.","Create the missing 'javascript' subfolder with at least one .html or .mjs file."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Check before calling findJSFilesInFolder\nconst fs = require('fs');\nfunction hasJSFolder(folder) {\n  return fs.existsSync(`${folder}/javascript`);\n}\n// skip folders without a javascript port instead of throwing","typeGuard":null,"tryCatchPattern":"// Already implemented in main() (build-index.js:134-139):\ntry { files = findJSFilesInFolder(folder); }\ncatch (error) { console.warn(`Game \"${name}\" is missing a javascript implementation: ${error.message}`); return null; }","preventionTips":["Treat the warning as informational: games without web ports are intentionally skipped.","Maintain IGNORE_FOLDERS_START_WITH for folders that should never be scanned.","Document that every numbered game is expected to ship a javascript/ subfolder."],"tags":["nodejs","build-script","missing-folder","filesystem"],"backgroundTag":null,"analyzedSha":"5301155192d91d74d337899cecc59dbda59c4c17","analyzedAt":"2026-08-13T19:29:00.979Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}